title: Spring-MVC form validation with MultiActionController
body: <p>I am trying to apply form validation on a MultiActionController (I do know that the controller classes are now deprecated).</p>
  
  <p>I've found this answer (which got me closer to my target, but not completely):
  <a href="https://stackoverflow.com/questions/2744587/how-to-perform-spring-validation-in-multiactioncontroller/2746912#2746912">How to perform Spring validation in MultiActionController?</a></p>
  
  <p>Ok, so according to the <a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/web/servlet/mvc/multiaction/MultiActionController.html" rel="nofollow noreferrer">javadoc</a>, an exception handler method is a controller's method with the parameters <code>(HttpServletRequest request, HttpServletResponse response, ExceptionClass exception)</code>.</p>
  
  <p>As far as I can see (correct me if I am wrong), it looks like the work flow is as follows: the spring dispatcher-servlet goes to the requested method of the controller, and if there happens an exception during its execution (e.g. a binding exception due to validation failure), it will go to the exception handler method that its exception parameter matches the occurring exception (if there is such an exception handler method).</p>
  
  <p>But unlike the regular controller's methods, this exception handler method has no command object parameter. <strong>So my question is how do I access in that method, the command object that was sent with the request in which the binding exception (due to a validation error) happened?</strong></p>
  
  <p>For example, when I use validation by annotations, I have in the request handler methods access <strong>(as method parameters)</strong> to both BindingResult and the command object, so in case of a validation error I can load the returned ModelAndView with the command object data.</p>
  
  <p>However, with my exception handler method (in my MultiActionController), which ends with </p>
  
  <pre><code>BindException bindException = (BindException) bindingException.getRootCause();
  return new ModelAndView("myFormView").addAllObjects(bindException.getModel());
  </code></pre>
  
  <p>— after submitting invalid data, I am getting and exception that my JSP view ("myFormView") cannot be rendered because the command object cannot be found.</p>
  
  <p>Thanks!</p>
  
  <p><strong>MORE INFO:</strong></p>
  
  <p>My actual request handler method in my controller (SearchBookController) looks like this:</p>
  
  <pre><code>public ModelAndView list(HttpServletRequest request, HttpServletResponse response, Book book) throws Exception {
  
      ModelMap modelMap = new ModelMap();
  
      //getting a list of books according to the propertiest of the command object book...
      modelMap.addAttribute("bookList", bookDAO.listBooks(book));
  
      return new ModelAndView("bookForm", modelMap);
  }
  </code></pre>
  
  <p>I've also added the following exception handler method to the controller:</p>
  
  <pre><code>public ModelAndView hanldeBindException(HttpServletRequest request, HttpServletResponse response, ServletRequestBindingException bindingException) {
      // do what you want right here
  
      //I WOULD LIKE TO ADD HERE THE SUBMITTED BOOK AND THE FETCHED BOOKLIST TO THE ModelAndView, BUT I DO NOT KNOW HOW TO DO IT
  
      BindException bindException = (BindException) bindingException.getRootCause();
      return new ModelAndView("bookForm").addAllObjects(bindException.getModel());
  }
  </code></pre>
  
  <p>This is how I added my validator to SearchBookController in my servlet-dispatcher.xml:</p>
  
  <pre><code>&lt;bean name="/book/search.htm" class="com.books.web.SearchBookController" p:validators-ref="searchBookValidator" &gt;
      &lt;property name="bookDAO" ref="myBookDAO" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="searchBookValidator" class="com.books.validator.SearchBookValidator" /&gt;
  </code></pre>
  
  <p>The validator right now just makes sure that the book properties are validated by ValidationUtils.rejectIfEmptyOrWhitespace.</p>
  
  <p>My view (bookForm.jsp) shows both the submit fields and the search results (it re-displays the submitted fields when the result view is rendered). So after the submit, the view should get both the book command object, and the bookList object.</p>
  
  <p>bookForm.jsp looks like this:</p>
  
  <pre><code>    &lt;tr&gt;
          &lt;td&gt;Details :&lt;/td&gt;
          &lt;td&gt;&lt;form:input path="details" /&gt;&lt;/td&gt;
          &lt;td&gt;&lt;form:errors path="details" cssClass="error"/&gt;&lt;/td&gt;
      &lt;/tr&gt;
  </code></pre>
  
  <p>(details is one of the fields of Book).</p>
  
  <p>Here is the exception message I am getting when I try to load bookForm.jsp (even before the submit, simply when i try to load the page so I could fill in the form):</p>
  
  <p>(*** When I remove the <code>p:validators-ref="searchBookValidator"</code> from the controller definition in the servlet-dispatcher.xml, the jsp page loads correctly before and after the submit).</p>
  
  <pre><code>HTTP Status 500 - 
  
  --------------------------------------------------------------------------------
  
  type Exception report
  
  message 
  
  description The server encountered an internal error () that prevented it from fulfilling this request.
  
  exception 
  
  org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/jsp/bookForm.jsp at line 209
  
  206:        --%&gt;
  207:        &lt;tr&gt;
  208:            &lt;td&gt;Details :&lt;/td&gt;
  209:            &lt;td&gt;&lt;form:input path="details" /&gt;&lt;/td&gt;
  210:            &lt;td&gt;&lt;form:errors path="details" cssClass="error"/&gt;&lt;/td&gt;
  211:        &lt;/tr&gt;
  212:        &lt;tr&gt;
  
  
  Stacktrace:
      org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
      org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:413)
      org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
      org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
      org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  
  
  root cause 
  
  java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'book' available as request attribute
      org.springframework.web.servlet.support.BindStatus.&lt;init&gt;(BindStatus.java:141)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:160)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:147)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:138)
      org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:122)
      org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:408)
      org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:140)
      org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
      org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
      org.apache.jsp.WEB_002dINF.jsp.bookForm_jsp._jspx_meth_form_005finput_005f0(bookForm_jsp.java:593)
      org.apache.jsp.WEB_002dINF.jsp.bookForm_jsp._jspService(bookForm_jsp.java:326)
      org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
      org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
      org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
      org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
      org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
  </code></pre>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Following the answer below, I can now access the command object from the exception handler method. I still have a problem though: if I submit data that should have triggered an error message, e.g. through</p>
  
  <pre><code>&lt;tr&gt;
      &lt;td&gt;Details :&lt;/td&gt;
      &lt;td&gt;&lt;form:input path="details" /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;form:errors path="details" cssClass="error"/&gt;&lt;/td&gt;
  &lt;/tr&gt;
  </code></pre>
  
  <p>in the result view JSP - I do not see that error message.</p>
  
  <p>My validator looks like this:</p>
  
  <pre><code>public class SearchBookValidator implements Validator {
  
      //......
  
      @Override
      public void validate(Object target, Errors errors) {
          ValidationUtils.rejectIfEmptyOrWhitespace(errors, "details", "details.required");
      }
  }
  </code></pre>
  
  <p>and my messages.properties contains the following line:</p>
  
  <pre><code>details.required=details are required
  </code></pre>
  
  <p>To help me see what happens, I've included the following code in my controller's hanldeBindException:</p>
  
  <pre><code>    Map mp = bindException.getModel();
      for (Object o : mp.entrySet()) {
          Map.Entry pairs = (Map.Entry)o;
          System.out.println(pairs.getKey() + " = " + pairs.getValue());
      }
  </code></pre>
  
  <p>When I submit the form with deliberately wrong data (i.e. the details text field is empty), I am getting the following input on the console:</p>
  
  <pre><code>command = com.books.domain.Book@1173447
  org.springframework.validation.BindingResult.command = org.springframework.validation.BeanPropertyBindingResult: 1 errors
  Field error in object 'command' on field 'details': rejected value []; codes [details.required.command.details,details.required.details,details.required.java.lang.String,details.required]; arguments []; default message [null]
  </code></pre>
  
  <p>Can you see why I do not get any error message through the <code>&lt;form:errors path="details" cssClass="error"/&gt;</code> ?</p>