Spring-MVC bean Validation Type mismtach error - spring

I am trying to validate an object using Spring JSR303 validation, i have a form object which have some nested objects along with some form properties here is my Form signature
public class PaymentDetailsForm
{
private AddressForm billingAddress;
// other properties and getter and setters
}
In my AddressForm bean i have used Bean validation annotations to validate data, but i am not using any #Valid annotation inside my PaymentDetailsForm for billingAddress.
This is the signature of my Controller method
public String createUpdatePaymentInfos(final Model model,
#ModelAttribute("paymentInfo") #Valid final PaymentDetailsForm form, final BindingResult bindingResult)
{
}
If i am sending correct data from the form everything is working perfectly fine, but if i omit any field from billingAddress which is marked as required or not null i am getting following binding error exception
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'paymentInfo' on field 'billingAddress':
rejected value [com.xxx.storefront.forms.AddressForm#e39f6f1,true];
codes [typeMismatch.paymentInfo.billingAddress,typeMismatch.billingAddress,typeMismatch.com.xxx.storefront.forms.AddressForm,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [paymentInfo.billingAddress,billingAddress]; arguments []; default message [billingAddress]];
default message [Failed to convert property value of type 'java.lang.String[]'
to required type 'com.xxx.storefront.forms.AddressForm' for property 'billingAddress';
nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String[]] to required type [com.xxx.storefront.forms.AddressForm] for property 'billingAddress':
no matching editors or conversion strategy found]
I was expecting that since i have not used #valid annotation for billingAddress property, it should not be validated but even in case it get validated i am not able to understand above mentioned exception/error

The bindingResult that you are seeing doesn't look like it is because of validation errors, it is likely because of the binding errors - not being able to bind the UI fields to the inner billingAddress field. Even the binding errors would end up showing in the immediately following bindingresult argument like you are seeing.

That was due to some wrong mapping from UI,in my JSP page i was mapping address fields to billingAddress object but there was one hidden field like
<form:hidden path="billingAddress" id="billingAddress"/>
This was the cause of error since it was trying to send String array and Spring binding was unable to distinguish what i am trying to do

Related

Spring annotation for making two fields mandatory out of four data fields

I have four data fields and i have to make sure that i receive data for at least two fields out of four. I am using spring 3 mvc and i wanted to know that if we have any annotation availabe in spring which can be used to group this not null logic across four fields.
Yes, You can do it by annotation #NotEmpty of Hibernate Validator it will check value to be not null and size is > 0
This annotation is given on fields of bean for which you need to make it required fields.
On client side if your are using Spring form tag than there is attribute modelattribute=BeanName which map your form fields to Bean fields.
On controller side you need to validate this bean before proceed it further, for this you need to include #valid annotation before your bean object argument in controller as show below
public String submitForm(#Valid MyBean myBean, BindingResult result, Model m)
{
if(result.hasErrors()) {
return "formPage"; //return to error page or display error on client side
}
m.addAttribute("message", "Successfully saved form: ");
return "formPage";
}
result.hasErrors() return true if fields value in invalid as per validation define in your bean class. It return false if all values are correct.
Here is complete example on Validate Form fields in Spring MVC.
This can be achieved by simply creating a custom validator annotation in spring

Optional form fields in spring-mvc liferay portlet application

I have a big form with a lot of date fields and int fields
my action phase methos is like this:
public void createCamapign(WebRequest request,ActionResponse response ,
Model model, #ModelAttribute("searchForm") CreateCampaignForm form) throws Exception{
where the form is my wrapper bean
anyway if i dont fill all the fields in the rendered form my application crashed with this error
[org.springframework.web.portlet.DispatcherPortlet] - Handler execution resulted in exception - forwarding to resolved error view
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'searchForm' on field 'activationDate': rejected value []; codes [typeMismatch.searchForm.activationDate,typeMismatch.activationDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchForm.activationDate,activationDate]; arguments []; default message [activationDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'activationDate'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'activationDate': no matching editors or conversion strategy found]
how or where do i specify that these fields are optional
by the way in the case of int fields i kinda resolved it by using Integer class, but i dont want to do the same with Date type attributes
I am not sure if I understood your problem correctly. I am not an expert in Spring.
Just a suggestion, like can you make use of dependency check and #Required annotation to make a few fields necessary and other ignorable.
You could try to put the DateTimeFormat annotation on you date fields, like this:
#DateTimeFormat(pattern = "dd/mm/yyyy") // put any pattern you want
private Date myDate;
Note: If you are using a version of Spring older than 3.2, you need to add joda date library to your project classpath

Spring MVC + Hibernate validator : how can I override/internationalize the default error messages?

I'm working on a Spring MVC project in which I'm using Hibernate Validator to validate input fields from a form. As my project is Maven-based, I added this dependency:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>4.1.0.Final</version>
</dependency>
The form validation process works fine but now, I would like to override or internationalize the default error messages.
For instance, by default, using the #NotEmpty annotation will yield the message "may not be empty". How I can replace this message by my own message? I've tried several solutions:
defining a Spring bean with id "messageSource" and setting its "basenames" property
creating ValidationMessages.properties file in the project classpath
But the default messages are still displayed...
Any hint?
Thx in advance.
Yes you can do that. You can load the error message from the properties files. But you need to have the key in a proper format. Like NotEmpty.ClassName.fieldName=fieldName Can not be empty.
You just need to specify your exact class name and property name in your properties files. Everything other is looking just perfect in your case.
You can also have a common error message for a particular type of validation annotation for all the fields having that annotation. Like javax.validation.constraints.NotNull=Notnull erro happened!
Hope this helps you. Cheers.
This is a bit explanation that how you can find the exact property name behind every annotation given or used for validation. See below mentioned steps.
#Size(min = 1, max = 50, message = "Email size should be between 1 and 50")
Now remove { message = "Email size should be between 1 and 50" } from validation tag.
After doing this your annotation will be like this.
#Size(min = 1, max = 50)
Now at controller side debug the method which is being called upon when submitting the form. Below is my method which is receiving the request when user hits submit.
public static ModelAndView processCustomerLoginRequest(IUserService userService,LoginForm loginForm,
HttpServletRequest request, HttpSession session, BindingResult result, String viewType, Map<String, LoginForm> model)
Now place a debug point at very first line of the method and debug the argument "result".
BindingResult result
While dubugging you will find a string like this in codes array.
Size.loginForm.loginId
Now define this string in your properties file and a message against that string. Compile and execute. That message will be displayed whenever that annotation wouldn't be validated.
Size.loginForm.loginId=email shouldn't be empty.
Basically spring makes its own string as key to its property file message. In above key
Size(#Size) = validation annotation name
loginForm = My Class Name
loginId = Property name in LoginForm class.
The Beauty of this method is it also runs fine while you will be using Spring Internationalization. It automatically switches the messages file as language changes.

Spring MVC Data Binding Error

I'm getting the following error when I try to retrieve the form results in controller method:
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'search' on field 'clients': rejected value [14]; codes [typeMismatch.search.clients,typeMismatch.clients,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [search.clients,clients]; arguments []; default message [clients]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'clients'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.Client] for property 'clients[0]': no matching editors or conversion strategy found]
Model Object looks like this:
public class SearchForm {
private String name;
private List<Client> clients;
//getters and setters
}
public class Client {
private String name;
private Int id;
}
form:
<form:form method="POST", name="searchresults.html" modelattibute="search">
<form:input path="name"/>
<form:checkboxes path="clients" items="{clientsList}" itemsValue="id" itemsLabel="name"/>
</form:form>
this form displays the values correctly on the html page but when I click the submit button I get the above error
The browser will only send a list of client IDs when the form is submitted. How could Spring know how to convert each ID into a Client instance. You either have to tell it how to do, or add a List<String> clientIds property to your bean, and make the form:checkboxes tag use this property instead of clients as its path.

Wrapping PropertyEdtior exceptions during Spring validation

When I submit a Spring form and a PropertyEditor fails to convert a value, an exception is thrown and a message like this ends up in my validator errors object:
Failed to convert property value of type java.lang.String to required type
org.joda.time.DateMidnight for property startDate; nested exception is
java.lang.IllegalArgumentException: Invalid format: "2010-111" is malformed at "1"
Can I wrap this somehow, providing a friendlier message to display on screen?
I'm using #Valid in my controller, with the following in my form:
#NotNull
protected DateMidnight startDate;
Thanks
This error message has message codes such as typeMismatch.objectName.startDate (see DefaultMessageCodesResolver). To display a user-friendly message, you need to declare a MessageSource with the corresponding messages.

Resources