Home > Spring, Spring MVC, Validation > How to configure validation in Spring MVC controllers

How to configure validation in Spring MVC controllers


Validation is the action through which the application checks that data respects logical (e.g. empty fields, invalid formatted values) and business (e.g. min/max values) constraints.

In order to configure validation for you model objects in Spring, you can follow these steps:

  1. Import the appropriate validation specification and validation implementation jars
  2. Define a class which implements the org.springframework.validation.Validator interface
  3. In the controller method signature, you must annotate the model attribute you’re trying to validate with @Valid (javax.validation.Valid)
  4. In the controller method, you must check whether errors have been identified
  5. If errors are found, reload the page and display the error messages.

In order to have an example on how this works, I’ve written a small test project, using Maven. I am using a jsp page which contains spring:form tags and an in-memory list of users, in order to simulate data access.

The jars needed to use validation are:

  • Java Bean Validation (JSR303) validation jar
  •  An implementation of JSR303. I’ve used Apache BVal: https://bval.apache.org/

The pom.xml dependencies are:

	
	<dependency>
		<groupId>javax.validation</groupId>
		<artifactId>validation-api</artifactId>
		<version>1.0.0.GA</version>
	</dependency>
	<dependency>
		<groupId>org.apache.bval</groupId>
		<artifactId>bval-jsr303</artifactId>
		<version>0.5</version>
	</dependency>

Next, I’ve defined a class implementing org.springframework.validation.Validator. The official Spring documentation on how to do this is here: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/validation.html, in section 7.2.

I’ve defined it as a bean so I could easily use it in the controller. In my validator class, I’ve checked whether the value for the username is empty and whether another user with the same username exists. In both cases, an error message is added to the validation result.

@Component
public class UserValidator implements Validator {
	public boolean supports(Class<?> clazz) {
		return UserDto.class.equals(clazz);
	}

	public void validate(Object target, Errors errors) {
		ValidationUtils.rejectIfEmpty(errors, "username", "username.empty",
				"Username Empty");
		UserDto u = (UserDto) target;
		if (!UserService.validateUser(u)) {
			errors.rejectValue("username", "username.already.exists",
					"Username Already Exists");
		}
	}

}

This validator is only valid for classes for which the supports method returns true.

I’ve then applied it to the corresponding model attribute in the controller. The reference documentation for this is the same as above, but section 7.8.4. At the same section, there is information regarding how to tell the controller to use the validator by using a WebDataBinder. In my example, the binder is initialized like this:

private UserValidator userValidator;

@Autowired
public void setUserValidator(UserValidator userValidator) {
	this.userValidator = userValidator;
}

@InitBinder
protected void initBinder(WebDataBinder binder) {
	binder.setValidator(userValidator);
}

, and the controller method that makes the validation has the following signature:

@RequestMapping(method = RequestMethod.POST)
public String saveUser(@ModelAttribute("user") @Valid UserDto user, BindingResult result)

In addition to the @Valid annotation, the argument is also annotated with @ModelAttribute(“user”). What happens is that Spring searches for an object in the model named userDto (the name of the class starting with lowercase). Not finding a model object under userDto, it will throw an exception. In order to tell Spring the correct name of the attribute, usage of @ModelAttribute is needed. I’ve found a quick and easy explanation here: http://blog.nigelsim.org/2011/09/07/spring-mvc-validation-bindingresult/

The BindingResult object is a special type of argument which is managed by Spring and can be added to methods annotated with @RequestMapping. It contains the validation errors for the method argument preceding it. More information about accepted method arguments can be found here: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#mvc-ann-arguments.

In this case, the BindingResult will contain all the validation errors for the UserDto object. Next, we use the BindingResult in the method content:

if (result.hasErrors()) {
	return "editUser";
}
UserService.updateUser(user);
return "success";

The only thing left is to show the errors in the page, by using the spring form:errors tag. Information on all form tags can be found here: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/view.html#view-jsp-formtaglib

<form:form commandName="user" method="POST">
	<form:errors path="*" cssStyle="color:red"/>
	...
</form:form>

You can find a full code example here: https://www.dropbox.com/s/6080kq784jwlgj3/spring.mvc.validation.7z

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s