Great tip regarding annotated Spring form validation & BindingResult

Found an interesting little gotcha at work last week, I was adding form validation to an annotated Spring controller, creating a custom Validator to do the work and wiring it in to the controller's method signature with the use of the BindingResult parameter (I just tacked it on the end of my existing parameters):

@RequestMapping(method=RequestMethod.POST, params="action=person")
public String createPerson(@ModelAttribute("person") PersonForm person, ModelMap model, BindingResult result) {
    // code goes here...
}
This resulted in a slightly odd error message:
java.lang.IllegalStateException: Errors/BindingResult argument 
declared without preceding model attribute. Check your handler method 
signature!
I was a little confused by this message, it was indicating that I didn't have the form's model attribute declared before the BindingResult but I certainly have. After some google searching for this error message I found a website created by a colleague of mine (Mark Lishman) which had just the answer that I needed:
The BindingResult parameter must be positioned directly after the corresponding model argument that is being validated.
Taken from the information tip box on the Level Up Spring MVC Form Validation page.
So basically it meant that my controller method should have been this:
@RequestMapping(method=RequestMethod.POST, params="action=person")
public String createPerson(@ModelAttribute("person") PersonForm person, BindingResult result, ModelMap model) {
    // code goes here...
}
Level Up is an excellent resource for people starting out with Spring, Hibernate & Oracle, check it all out at the Level Up website.

Technorati Tags: , , , , ,

13 comments:

Yatish Sonkeshariya: said...

Thanks vry much for this post. I face thsi problem and solved it using thsi post n save time.....

Thanks vry much..

Yatish Sonkeshariya said...

Could i use BindingResult parameter with a handle-method that is marked with @RequestMapping(method = RequestMethod.GET)???

Anonymous said...

To use BindingResult parameter with a method that is marked with @RequestMapping(method = RequestMethod.GET), just use @ModelAttribute like this:-

@RequestMapping(method = RequestMethod.GET)
public void setupForm(Model model, @ModelAttribute NameOfYourrCommandObject cmd, BindingResult errors, HttpServletRequest request, HttpSession session)

Anonymous said...

To use BindingResult parameter with a method that is marked with @RequestMapping(method = RequestMethod.GET), just use @ModelAttribute like this:-

@RequestMapping(method = RequestMethod.GET)
public void setupForm(Model model, @ModelAttribute NameOfYourrCommandObject cmd, BindingResult errors, HttpServletRequest request, HttpSession session)

Benny Neugebauer said...

Thank you very much! The solution is ridiculous but it has helped. :)

Fl1ppeR said...

Thank you so much!

This was very very helpful!

Anonymous said...

Muchas gracias por el aporte, no tenia idea de que fuera, esa sencilles el problema, un saludo y gracias nuevamente por compartir.

Jorge

Anonymous said...

you saved me..thanks from an indian ;)

Willem Vermeer said...

Thank you for posting this!

Jety said...

Hello, I was facing the same problem caused by adding new Model parameter to the signature - thanks for the tip :)

Anonymous said...

Thanks !!! :)

Avishekh Sinha said...

Cool !! this was the Blog where i shopped my search .. exactly the thing what i was looking for

Avishekh Sinha said...

Cool !! this was the Blog where i shopped my search .. exactly the thing what i was looking for