title: Display JSR-303 errors before form submission with Spring MVC
body: <p>Is there an easy way in Spring MVC 3.x to display form error messages (obtained by JSR303 validation), before submiting the form ?</p>
  
  <p>Consider the example code at the end of this post.</p>
  
  <p>The end-user is supposed to edit forms in which the initial data is already invalid.</p>
  
  <p>Errors are properly displayed when the form is submitted (POST method), but not on initial form display (GET method).</p>
  
  <p>Is there an easy way to display the errors on initial form display (GET method) ? (Is there a way to re-use the form:errors tag for this purpose?)</p>
  
  <p><strong>JSP View</strong> form1.jsp:</p>
  
  <pre><code>&lt;%@ page session="true" %&gt;
  &lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;
  &lt;%@ taglib uri="http://www.springframework.org/tags" prefix="s" %&gt;
  &lt;%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %&gt;
  &lt;html&gt;&lt;body&gt;
  &lt;form:form commandName="form1" method="post"&gt;
   &lt;s:bind path="*"&gt;
     &lt;c:if test="${status.error}"&gt;
         &lt;div style="color: red;"&gt;There are errors:&lt;/div&gt;
         &lt;form:errors /&gt;&lt;br /&gt;
     &lt;/c:if&gt;
    &lt;/s:bind&gt;
  
    &lt;form:label path="field1" &gt;Field1:&lt;/form:label&gt; 
    &lt;form:input path="field1" /&gt;
    &lt;form:errors path="field1" cssStyle="color: red;"/&gt;
    &lt;br /&gt;
  
    &lt;form:label path="field2" &gt;Field2:&lt;/form:label&gt; 
    &lt;form:input path="field2" /&gt;
    &lt;form:errors path="field2" cssStyle="color: red;"/&gt;
    &lt;br /&gt;
  
    &lt;form:button name="submit"&gt;Ok&lt;/form:button&gt;
  &lt;/form:form&gt;
  &lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <p><strong>Controller</strong>:</p>
  
  <pre><code>@Controller @SessionAttributes("form1")
  public class Form1Controller {
  
  @ModelAttribute("form1") public Form1Bean createForm1() { return new Form1Bean(); }
  
  @RequestMapping(value = "/form1/edit", method = RequestMethod.GET)
  public String getEdit(Model model) {
      // here we pretend to get form1 from database, and store it in session.
      // form1 in database may have invalid field values.
  
      // Perform a JSR-303 validation here ?
      // MAIN QUESTION: What's the easy way to add errors to model and display them ?
  
      return "/form1";
  }
  
  @RequestMapping(value = "/form1/edit", method = RequestMethod.POST)
  public String postEdit(@Valid @ModelAttribute("form1") Form1Bean form1, BindingResult result, Model model) {
      if (result.hasErrors()) {
          return "/form1";
      } else {
          return "redirect:/done";
      }
  }
  
  }
  </code></pre>
  
  <p><strong>Backing Bean</strong>:</p>
  
  <pre><code>public class Form1Bean {
  @Size(min=4,max=10) private String field1; // getters and setters ommited for brevity
  @Size(min=4,max=10) private String field2;
  
  public Form1Bean() {
      this.field1 = "bad"; this.field2="good"; // start with an invalid field1
  }
  //...
  }
  </code></pre>
  
  <p>Edit: After the interpreting the answer from @jb-nizet, here is the complete <strong>controller source</strong>:</p>
  
  <pre><code>@Controller @SessionAttributes("form1")
  public class Form1Controller {
  
  @Autowired org.springframework.validation.Validator validator;
  
  @ModelAttribute("form1") public Form1Bean createForm1() { return new Form1Bean(); }
  
  @RequestMapping(value = "/form1/edit", method = RequestMethod.GET)
  public String getEdit(@ModelAttribute("form1") Form1Bean form1, Errors errors, Model model) {
      // here we pretend to get form1 from database, and store it in session.
      // form1 in database may have invalid field values.
  
      validator.validate(form1, errors);
  
      return "/form1";
  }
  
  @RequestMapping(value = "/form1/edit", method = RequestMethod.POST)
  public String postEdit(@Valid @ModelAttribute("form1") Form1Bean form1, BindingResult result, Model model) {
      if (result.hasErrors()) {
          return "/form1";
      } else {
          return "redirect:/done";
      }
  }
  
  }
  </code></pre>
  
  <p>Made a few tests, and it seems to work! Than you @jb-nizet</p>