Gotcha’s showing error messages with Spring forms (form:errors)

(I have recently encountered this with Spring 3.1)

Want to validate your forms using Spring? Are you using the form tag and bind it with an object? Got the validator working? But still you just can’t seem to get these error messages showing up? Here is a gotcha that might help you out!

Consider this controller:

@Controller
public class FormController {

    @RequestMapping("/form")
    public ModelAndView handleGet(@Valid TellAFriendForm backingForm, BindingResult bindingResult) {
        ModelAndView modelAndView = new ModelAndView("backingForm");
        modelAndView.addObject("backingForm", backingForm);
        modelAndView.addObject("result", bindingResult);
        return modelAndView;
    }

}

With this jsp:

<form:form method="POST" commandName="myForm" action="?">
    <div>
        <label for="name">Name*</label>
        <form:input path="name" id="name"/>
        <form:errors path="name"/>
    </div>
    <div>
        <input type="submit" value="Send"/>
    </div>
</form:form>

When the user submits this form, the form should be validated. Whenever a field does not validate, it should inform the user about this.

This is done by using:

        <form:errors path="name"/>

Where ‘path’ refers to a field in the bound form object, in this case myForm. In this example, I have named my form “myForm”. The theory is that when the form is being validated, the BindingResult (put as “result” on the model), contains all fields that have validation errors. Using the form:errors tag you can make use of that and show error messages.

Although this works often, sometimes it does not and you spend some time figuring out why. A common gotcha is that you forget to put the bindingResult on your model (as “result”).

But there is another less intuitive gotcha.

When your given commandName in the form:form tag does not represent the camelcased, name of the type of the form, the form:errors tag will *not* work. So don’t make up your own name. Make sure it is the same as the type, and make sure it is camelcased correctly. I figured this out the hard way.

Solution: The form object is of type: BackingForm, the expected name would then be backingForm. Change the commandName into backingForm and you will see the form error messages showing up.

Comments

  1. Or you could accept your form/model as model attribute in which you declare the name of the command that it should be bound to. e.g.:
    public String saveUser(@ModelAttribute(“myOwnName”) UserModel userModel, BindingResult result)….

    now the errors will be stored in a command object with the name myOwnName. If youi had not set the name it would have been available using the object name as parameter so without the name it would have been bound with the name “userModel”

    Regards
    Ronald

    1. Hi Ronald,

      Thanks for your reply. Good to know that using the modelattribute annotation can also be used. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.