Use a Formatter and/or converter from Spring instead of rolling you own. That will be called for rendering and parsing the result.
How to encrypt and decrypt id of an object with spring mvc
-
29-06-2022 - |
Pregunta
I have a problem which is as following - Have a jsp page Register.jsp which has form like this -
<form:form modelAttribute="user" action="Register" class="form-horizontal col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 col-sm-12 col-xs-12" method="POST" role="form" autocomplete="off">
<fieldset>
<legend>Basic Info</legend>
<div class="form-group">
<form:label path="firstName" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">First Name <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input path="firstName" type="text" name="firstName" id="firstName" class="capitalize form-control required" required="true" />
<form:errors path="firstName" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="secondName" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Middle Name</form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input path="secondName" type="text" name="secondName" id="secondName" class="capitalize form-control" />
<form:errors path="secondName" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="lastName" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Last Name <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input type="text" name="lastName" path="lastName" id="lastName" class="capitalize form-control" required="true" />
<form:errors path="lastName" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="email" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Email <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input type="email" path="email" name="email" class="form-control" required="true" />
<form:errors path="email" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="dob" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">DOB <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input path="dob" type="date" name="dob" class="dob form-control" required="true" />
<form:errors path="dob" cssClass="error" element="label"></form:errors>
</div>
</div>
<c:set var="converter" value="${converter}"></c:set>
<div class="form-group">
<form:label path="city.state.country.id" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Country <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:select path="city.state.country.id" name="country" class="form-control" required="true">
<c:forEach items="${countries}" var="country">
<option value="${converter.encryptAnID(country.id)}"><c:out value="${country.name}"></c:out></option>
</c:forEach>
</form:select>
<form:errors path="city.state.country.id" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="city.state" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">State <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:select path="city.state.id" name="city" class="form-control" required="true">
<c:forEach items="${states}" var="state">
<form:option value="${converter.encryptAnID(state.id)}"><c:out value="${state.name}"></c:out></form:option>
</c:forEach>
</form:select>
<form:errors path="city.state.id" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="city.name" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">City <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input path="city.name" type="text" name="city" id="city" class="capitalize form-control" required="true"/>
<form:errors path="city.name" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<form:label path="zip" class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Pincode/ZIP <b>*</b></form:label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<form:input path="zip" type="text" name="zip" id="zip" class="form-control" required="true"/>
<form:errors path="zip" cssClass="error" element="label"></form:errors>
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4">Solve equation </label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<img src="<c:url value='/Captcha'></c:url>">
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4 col-md-4 col-sm-4 col-xs-4" for="captcha">Solution <b>*</b></label>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8">
<input name="captcha" id="captcha" class="form-control" type="text" value="" required="true"/>
</div>
</div>
<div class="form-group">
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-8 col-lg-offset-4 col-md-offset-4 col-sm-offset-4 col-xs-offset-4">
<button type="submit" class="btn btn-primary">Register</button>
<button type="reset" class="btn btn-default">Reset</button>
</div>
</div>
</fieldset>
</form:form>
as you can see i am encrypting id of country and states at jsp Now the controller method which handles this request is like this -
@RequestMapping(value="/Register",method= RequestMethod.POST)
public String register(@ModelAttribute("user") @Valid User user, BindingResult bindingResult){
if(bindingResult.hasErrors()){
System.out.println("Errors detected");
List<ObjectError> errors = bindingResult.getAllErrors();
for(ObjectError error:errors){
System.out.println(error.toString());
}
return "Register";
}else{
return "redirect:/Home";
}
}
User bean has a property called country which references object Country class Here is my country Class -
@Entity
@Table(name="country"
,catalog="tutor"
)
public class Country implements java.io.Serializable {
private Integer id;
private String name;
private String code;
private List<State> states = new ArrayList<State>(0);
public Country() {
}
public Country(String name, String code) {
this.name = name;
this.code = code;
}
public Country(String name, String code, List<State> states) {
this.name = name;
this.code = code;
this.states = states;
}
@Id @GeneratedValue(strategy=IDENTITY)
@Column(name="id", unique=true, nullable=false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="name", nullable=false, length=45)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="code", nullable=false, length=2)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="country")
public List<State> getStates() {
return this.states;
}
public void setStates(List<State> states) {
this.states = states;
}
}
after submitting the form i get this error -
Failed to convert property value of type java.lang.String to required type java.lang.Integer for property city.state.country.id; nested exception is java.lang.NumberFormatException: For input string: "204169936916065690991063869295677385346323054608"
Problem is obvoius id of the country is integer but after encryption the value of option is string and unable to cast it into integer. So is there any way to instruct controller or bean to decrypt this value with a method defined and which will take string parameter and return integer before validation.
Solución