Form Validation in Spring MVC 3 using Hibernate Validator (JSR 303)

Previous example shows how form validation is done in Spring MVC 3 using validator class. In this tutorial we will learn how Spring MVC uses Hibernate Bean Validator framework to apply form validation.

We will modify our previous example on Form Validation in Spring MVC 3 using XML Configuration to use Hibernate Bean Validator Framework (JSR 303 implementation).

Hibernate Bean Validator Framework uses annotations to apply validation rules on properties of a bean. To use Hibernate Bean Validator Framework with Spring MVC 3 we need to add some jar files related to bean validator and it’s dependencies. Following are the jar files we have to add :

  • hibernate-validator-4.0.2.GA.jar
  • log4j-1.2.16.jar
  • slf4j-api-1.5.10.jar
  • slf4j-log4j12-1.5.10.jar

These jars are included in the war file of this example. You can download the war file to get the jars.

Following are some of the annotations of Hibernate Validator that can be used to validate bean properties :

  1. @NotNull : Property can not be null. Applicable to class instances only, not to primitive types.
  2. @NotEmpty : Property can not be null or empty.
  3. @Null : Property should be null. Applicable to class instances only, not to primitive types.
  4. @Length : Used to define min and max length of a string.
  5. @NumberFormat : Can define a particular number format or style to String.
  6. @Min : Used to apply constraint on minimum value of number.
  7. @Max : Used to apply constraint on maximum value of number.
  8. @Valid : Applicable to an class instance. Class should also use Hibernate Validator constraint and the instance will be valid if all constraint defined in class are fulfilled.
  9. @AssertTrue : Applicable to boolean property only. The property must be true.
  10. @AssertFalse : Checks that the annotated elements are false;
  11. @CreditCardNumber : Used to check if a number is a credit card number or not.
  12. @DecimalMax : Applicable to BigDecimal, BigInteger,String, byte, short, int, long and respective wrapper classes. For min value check.
  13. @DecimalMin : Applicable to BigDecimal, BigInteger,String, byte, short, int, long and respective wrapper classes. For max value check.
  14. @Future : Applicable to Date or Calender instance. The time must be in future means after today.
  15. @Past : Applicable to Date or Calender instance. The time must be in past means before today.

Now, lets start with example to implement the validation using hibernate bean validation in spring mvc 3. We will follow following steps to modify our previous example of form validation :

  1. First of all we will modify our command class (RegistrationBean.java) to include hibernate bean validation annotations.
  2. Then we will change our controller (RegistrationController.java) to make it annotation driven.
  3. Will make changes in spring mvc 3 configuration file (app-config.xml) to make configuration annotation driven.
  4. Then we will make changes to the existing validator class (RegistrationValidator.java) to handle only class level validation.

RegistrationBean.java

Our command class RegistrationBean.java will be modified as follows to make the support of hibernate bean validation :


package com.raistudies.domain;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;

public class RegistrationBean {

    @NotEmpty(message="Name field is mandatory.")
    private String name = null;

    @NotEmpty(message="Username field is mandatory.")
    private String username = null;

    @NotEmpty(message="Email field is mandatory.")
    private String email = null;

    @Length(max=10,min=10,message="Phone number is not valid. Should be of length 10.")
    @NotEmpty(message="Phone field is mendatory.") @NumberFormat(style= Style.NUMBER)
    private String phone;

    @NotEmpty(message="Password should not be empty.")
    private String password = null;

    @NotEmpty(message="Retype Password should not be empty.")
    private String rePassword = null;

    // Getter and setter are omitted to make the code short.
}

You can apply our custom error message using “message” attributes in annotations. Other attributes are required as per the annotations.

RegistrationController.java

We have to change our controller class to work with annotation configurations.

package com.raistudies.controllers;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.raistudies.domain.RegistrationBean;
import com.raistudies.validator.RegistrationValidator;

@Controller
@RequestMapping(value="/registration.htm")
public class RegistrationController {
    RegistrationValidator validator = null;

    public RegistrationValidator getValidator() {
        return validator;
    }

    @Autowired
    public void setValidator(RegistrationValidator validator) {
        this.validator = validator;
    }

    @RequestMapping(method=RequestMethod.GET)
    public String showForm(ModelMap model){
        RegistrationBean userRegis = new RegistrationBean();
        model.addAttribute("Registration", userRegis);
        return "registration";
    }

    @RequestMapping(method=RequestMethod.POST)
    public String processForm(@ModelAttribute(value="Registration") @Valid RegistrationBean userRegis,BindingResult result){
        validator.validate(userRegis, result);
        if(result.hasErrors()){
            return "registration";
        }else{
            return "success";
        }
    }
}

You can find some new things in our controller class. Here is the explanation :

  • @Valid : the new annotation @Valid has been associated with the ModelAttribute or command instance. It is the part of the Hibernate Bean Validation. It will indicate to Spring MVC that the RegistrationBean instance should be a valid instance according to Hibernate Bean Validation Framework and if any error are there then put the errors in BindingResult instance.
  • @Autowired : We have also used our previous validator class with containing only one class level validation and make our validation class a spring bean. @Autowired annotation tells Spring IoC to inject the instance of our valitator bean to our controller. It is mainly a part of Spring IoC and will take detail description in our next tutorial.

app-config.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- Application Message Bundle -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/messages" />
        <property name="cacheSeconds" value="3000" />
    </bean>

    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="com.raistudies" />

    <!-- Configures the @Controller programming model -->
    <mvc:annotation-driven />

    <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

Our Spring MVC configuration file is changed only to make support of annotation based configuration in our example project.

RegistrationValidator.java

RegistrationValidator.java has been changed to remove property level validations and to make the class as spring bean using annotation.


package com.raistudies.validator;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.raistudies.domain.RegistrationBean;

@Component
public class RegistrationValidator implements Validator {

    @Override
    public boolean supports(Class c) {
        return RegistrationBean.class.isAssignableFrom(c);
    }

    @Override
    public void validate(Object command, Errors errors) {
        RegistrationBean regBean = (RegistrationBean)command;
        if(!regBean.getPassword().equals(regBean.getRePassword()))
            errors.rejectValue("rePassword","password.notmatch");
        }
}

Here, you will find a new annotation @Component. This is a class level annotation that makes the class a spring bean ans spring can inject instance of this class when ever required in spring dependency solution.

Now, deploy the war in tomcat 6 and hit the url in browser you will get following screen :

Form Validation in Spring MVC 3 using Annotation

Form Validation in Spring MVC 3 using Annotation

You can check the validation by simply clicking on “Register” button without filling any data, you will get the screen :

Validation Errors in Spring MVC 3 using Hibernate Validator

Validation Errors in Spring MVC 3 using Hibernate Validator

Try out other validations and then when you fill correct values, you will get following screen :

Form Validation Success in Spring MVC 3 using Annotation

Form Validation Success in Spring MVC 3 using Annotation

That all from Spring MVC form validation using Hibernate Bean Validator Framework. You can download code or war for the example using following links :

Source : Doenload

War : Download

Related Posts:

Leave a comment ?

7 Comments.

  1. You pretty much said what i could not effectively communicate. +1

    My blog:
    dsl vergleich klick hier

  2. Keep up this good work, you have a nice blog over here with much good information! When you post some new stuff, I’ll visit your blog again and I’ll follow it.

  3. Awesome blog over here! Thanks for sharing this very usefull information. I will visit your blog again into a couple off days to check if you have some new articles.

  4. Hi , thanks for the post.

    one thing I could not manage to solve is when you type password and repassword which are not identical I’m getting exception – NosuchMessage

    you did not mention anything about this..

    if you can exaplain this a bit more it’ll be great
    thanks!

  5. Nice post. Was wondering if it is possible to only return 1 error / field with JSR303 and how?

Leave a Comment Cancel reply

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>