Validation in Spring 3 MVC App


Validating user inputs is an important function for most web applications. Typically, you need to validate the values a user enters, e.g. via a web form, to ensure that all the required fields are provided and that the values are acceptable according to the system’s business rules and logics.

This article demonstrates how to setup Spring 3 MVC web applications to support bean validation with JSR 303, as well as extending the standard validation capability by adding custom validators.

Set up Spring 3 validation support

Enabling JSR-303 bean validation support in Spring 3 is straight forward. Just add the following bean definition in your application context xml file:

    <bean id=”validator” class=”org.springframework.validation.beanvalidation.LocalValidatorFactoryBean”

From the javadoc, the above class is:

the central class for javax.validation (JSR-303) setup in a Spring application context: It bootstraps a javax.validation.ValidationFactory and exposes it through the Spring org.springframework.validation.Validator interface  as well as through the JSR-303 javax.validation.Validator interface and the javax.validation.ValidatorFactory interface itself.

Basically, what it means is it allows you to inject the above bean directly into any other bean without the need to access the factory. We will encounter an example later in this article when writing a custom bean to support cross field validation.

Note you will need to add the following dependency if you are using Maven:


Bean validation in Spring 3 MVC – An Example

Now we can add validation annotations to the bean. For example,

public class MyBean {

private String requiredStr; // cannot be null

private int positiveInt; // positive integer

Other useful validators include:

  • Digits – a number within a specified range
  • Future – a future date
  • Past – a past date

See javadoc for a complete list of standard annotations supported in JSR-303. You can also use the following non-standard validators if you are using Hibernate:

  • Email – a valid email address
  • Length – a string has length within min and max lengths
  • NotEmpty – string not null or blank
  • Range – between a min and max values

Then, use @Valid in the request mapping method of a Spring MVC controller. To validate the above object:

@RequestMapping(method = RequestMethod.POST)
public String handleFormSubmission(@Valid MyBean mybean, BindingResult result) {
if (result.hasErrors()) {
// model has error(s)

Any validation errors are included in the BindingResult object. Validating error messages can be defined using “message” attribute of the validating tag. Alternatively, you can define messages using keys in a properties file. The key is in the format <validator>.<object name>.<property>. For example,

NotNull.myobj.requiredStr=This string is required

Min.myobj.positiveInt=Must be a positive value

Writing Custom validation annotation

It is also possible to write your own validating annotation. First, define the annotation interface. For example:

@Target({ElementType.METHOD, ElementType.FIELD})
public @interface CreditCard {

String message() default “{com.rlee.CreditCardValidating.message}”;

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default {};

Next write the implementing class

public class CreditCardValidator implements ConstraintValidator<CreditCard, String> {

public void initialize(CreditCard constraintAnnotation) {

public boolean isValid(String value, ConstraintValidatorContext context) {


Note the validator needs to implement the generic ConstraintValidator class.

Writing custom validator for cross field validation

In many cases, an application will need to perform validations across multiple fields. For example, the minimum value of one field may depend on the chosen value of another field. In such case, a custom bean validator is required. Spring MVC allows you to do this easily by supporting binding of the custom validator to a controller using the @initBinder tag and method:

public class MyController {

private MyValidator myValidator;

protected void initBinder(WebDataBinder webDataBinder) {

The custom validator must implement Spring validator interface org.springframework.validation.Validator:

public class MyValidator implements Validator {

private Validator validator;

public boolean supports(Class<?> clazz) {


public void validate(Object target, Errors errors) {
// customer validation here

// delegate to standard validator

validator.validate(target, errors);

Note the injection of the standard validator, i.e. LocalValidatorFactoryBean.