Pages

Integration of Spring MVC with JSR 303 Validation

Spring supports JSR-303 validation Specification with Spring mvc. You can enable <mvc:annotation-driven /> to support JSR-303 validation.

To integrate JSR-303 bean validation, these are following steps to enable bean validation.

Step 1: Insert following dependency for apache tiles 3 and Spring MVC in pom.xml.
    
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.2.0.Final</version>
        </dependency> 


Step 2: Make a entry in root-servlet.xml file for loading the properties file using Spring's ReloadableResourceBundleMessage class.

     <mvc:annotation-driven />  
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:message_en" />
  </bean>


Note: define only properties's filename for value attribute, we put properties file at the classpath.

Step 3: we configured Controller class for JSR-303 validation by using @Valid annotation. This annotation automatically validate the fomBean if validation fails it returns to the same view and display the proper error message from the properties file at the classpath.

package controller;

import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import formbean.TestForm;

@Controller
@RequestMapping("/login")
public class TestController {
   
    @RequestMapping(value={"/index","/"})
    public ModelAndView  index(){
        ModelAndView modelAndView = new ModelAndView("index");
        modelAndView.addObject("testForm", new TestForm());
        return modelAndView;
    }

    @RequestMapping(value = "/submit", method=RequestMethod.POST)
    public ModelAndView submit(@Valid TestForm testForm, BindingResult result) {
        ModelAndView modelAndView ;
        if(result.hasErrors()) {
            modelAndView = new ModelAndView("welcome");
        } else {
            modelAndView = new ModelAndView("home");
        }
        modelAndView.addObject(testForm);
        return modelAndView;
    }
   
    @RequestMapping("/layout")
    public ModelAndView welcomePage() {
        ModelAndView modelAndView = new ModelAndView("welcome");
        modelAndView.addObject("testForm", new TestForm());
        return modelAndView;
    }
   
    @RequestMapping(method=RequestMethod.GET)
    public String createLoginForm(@RequestParam String user1, Model model) {
        model.addAttribute(new TestForm());
        return "welcome";
    }   
}


Step 4: declare the JSR-303 annotation on required properties in form bean for JSR-303 validation. we didn't declare the custom message in each property instead we keep all message in the message_en.properties file at the classpath.

package formbean;

import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;

public class TestForm {
   
    @NotEmpty
    @Size(min=3, max=6)

    private String firstName;
   
    @NotEmpty
    @Size(min=3, max=6)

    private String lastName;
   
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLa/stName(String lastName) {
        this.lastName = lastName;
    }
}


Step 5 : declare the all error message in message_en.properties file under at src/main/resources/message_en.properties.

NotEmpty.testForm.firstName=first name is required
Size.testForm.firstName=first name must be between 3 and 6 characters long
Size.testForm.lastName=last name must be between 3 and 6 characters long

Step 6: Bind the error message in jsp file as below.

<%@ page contentType="text/html; charset=ISO-8859-1" %>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags/form" %>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome Page</title>
</head>
<body>

<spring:form commandName="testForm" action="/login/submit" method="POST">
    <table>
        <tr> <td>First Name :: </td>
            <td><spring:input path="firstName" /><br>
                <font color="red"><spring:errors path="firstName"/></font>
            </td>       
        </tr>
        <tr> <td>Last Name :: </td>
            <td><spring:input path="lastName" /><br>
                <font color="red"><spring:errors path="lastName"/></font>
            </td>       
        </tr>
        <tr>
            <td><input type="submit" value="submit" /></td>       
        </tr>
    </table>
</spring:form>
</body>
</html>




Note: By default, if validation failed.
  1. @NotEmpty will display “may not be empty”
  2. @Range will display “must be between 1 and 150″
You can override it easily, create a properties with “key” and message. To know which @annotation bind to which key, just debug it and view value inside BindingResult result“. Normally, the key is “@Annotation Name.object.fieldname“.