0

I am new to Spring 3 MVC and was trying out a simple validation example. Below is the controller class:

@Controller
public class ValidationController {

@RequestMapping(value="/input")
public String displayForm(ModelMap model){      
    model.addAttribute("empl",new Employee());
    return "input";
}

@RequestMapping(value="/validate", method = RequestMethod.POST)
public String validateForm(@Valid Employee empl, BindingResult result, ModelMap m){
    if(result.hasErrors()){
        System.out.println("Validation Failed!!!");
        return "input";
    }else{
        System.out.println("Validation Succeeded!!!");
        return "done";
    }
}
}

Employee.java

@Size(min=2,max=30)
private String name;
@NotEmpty @Email
private String email;
@NotNull @Min(18) @Max(35)
private Integer age;
@Size(min=10)
private String phone;
    // Getters and Setters

Below is the input.jsp file:

<form:form method="post" commandName="empl" action="validate">
<table>
    <tr>
        <td>
            <label for="nameInput">Name:</label>
        </td>
        <td>
            <form:input path="name" id="nameInput"/>
            <form:errors path="name" cssClass="error"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="ageInput">Age:</label>
        </td>
        <td>
            <form:input path="age" id="ageInput"/>
            <form:errors path="age" cssClass="error"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="phoneInput">Phone:</label>
        </td>
        <td>
            <form:input path="phone" id="phoneInput"/>
            <form:errors path="phone" cssClass="error"></form:errors>
        </td>
    </tr>
    <tr>
        <td>
            <label for="emailInput">Email:</label>
        </td>
        <td>
            <form:input path="email" id="emailInput"/>
            <form:errors path="email" cssClass="error"></form:errors>
        </td>
    </tr>
            <tr>
        <td colspan="2">
            <input type="submit" value="Submit">
        </td>
    </tr>
</table>
</form:form>

Problem:

On click of the submit button of theinput.jsp` file, I am getting the below exception:

org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'empl' available as request attribute
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:502)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:424)
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:262)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1180)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:950)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

For resolving this I changed the validation method like this:

@RequestMapping(value="/validate", method = RequestMethod.POST)
public String validateForm(@Valid Employee empl, BindingResult result, ModelMap m){
    if(result.hasErrors()){
        System.out.println("Validation Failed!!!");
        m.addAttribute("empl",new Employee());
        return "input";
    }else{
        System.out.println("Validation Succeeded!!!");
        return "done";
    }
}

And now the error messages are not getting displayed.

Kindly help me in resolving this so that the validation error messages gets displayed in the input.jsp screen.

user182944
  • 7,897
  • 33
  • 108
  • 174

2 Answers2

1

You need to add @ModelAttribute("empl") right before @Valid, in order for Spring MVC to be able to know that it should populate the model object with the inputs of the form with commandName="empl"

Your controller method should look like

public String validateForm(@ModelAttribute("empl") @Valid Employee empl, BindingResult result, ModelMap m)

When you are trying to display errors in a form Spring MVC needs to have a reference to the offending model. So when you changed your code and added new Employee() there where no errors on that object.

This SO post has a good explanation of what @ModelAttribute does as does this and this blog post

Community
  • 1
  • 1
geoand
  • 60,071
  • 24
  • 172
  • 190
  • Thanks for the explanation. But my question is: without using `@ModelAttribute` also the values are coming in the `@Controller` class. I went through the links but it did not answer my doubt. – user182944 May 07 '14 at 01:39
  • Also, in thiese URL's I can see they have not used any @ModelAttribute - WHY? Please clarify. The URL's I followed are: 1) http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/ 2) http://www.journaldev.com/2668/spring-mvc-form-validation-example-using-annotation-and-custom-validator-implementation – user182944 May 07 '14 at 02:03
  • I am not exactly sure why in those tutorials they are able to omit `@ModelAttribute`. I could not find anything specific on that issue – geoand May 07 '14 at 07:02
  • 1
    @user182944 @geoand If you omit `@ModelAttribute`, a form bean will be exposed as a model attribute using its class name ("employee" in your case) by default. See [this](http://docs.spring.io/spring/docs/3.2.8.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-arguments) section of the reference manual for details. – Shinichi Kai May 07 '14 at 14:09
  • @ShinichiKai Very good explanation! I had missed that part of the documentation – geoand May 07 '14 at 16:12
0

Use

<form:form method="post" modelAttribute="empl" action="validate"></form> 

in form instead of

<form:form method="post" commandName="empl" action="validate">
Ravi Kumar
  • 993
  • 1
  • 12
  • 37