Declarative Input Validation

Spring 3 supports JSR-303 Bean Validation API to perform declarative input validations.

You can apply declarative validation with help of

  1. Bean Validation API 1.1 annotations

  2. Hibernate Validator 5.0.1.Final annotations.

Here is example code of UserValidationForm bean that applies Basic and Hibernate validations.

Form Bean

public class UserValidationForm {

@Min(value = 1, message = "Id must be a positive number.")

private long id = 0L;

@NotNull(message = "First Name can not be Null.")

@Size(min = 5, max = 50)

private String firstName = null;

@NotNull(message = "Last Name can not be Null.")

@Size(min = 5, max = 50)

private String lastName = null;

@NotNull(message = "Gender can not be Null.")

@Size(min = 1, max = 6)

private String gender = null;

@Min(value = 13, message = "Age must be beatween 13-90.")

@Max(value = 90, message = "Age must be beatween 13-90.")

int age = 0;

...

Annotation@NotNull, @Min, @Max and @Size are the basic validation annotations. Attribute values in an annotation set the error message and other restrictions. For example min and max attributes of @Size annotation, validate the minimum and maximum size of a string.

Additional validations can be applied by Hibernate validation annotations. Here is example of applying @Email and @URL validation of hibernate annotation.

@Email(message = "Invalid Email ID.")

private String email = null;

@URL(message = "Invalid URL")

private String url = null;

Controller

Annotation @Valid is used to enable validation on a bean. If validation is failed, error messages are set into BindingResult object. You can call hasErrors() method of BindingResult to check if there is any validation error and take corrective path.

Here is sample code that will print all error messages at console.

@Controller

@RequestMapping(value = "/FormBinding")

public class FormBindingCtl {

@RequestMapping(value = "/user", method = RequestMethod.POST)

public String userSubmit( @ModelAttribute("userForm") @Valid UserValidationForm userFrom, BindingResult result,

Model model){

if (result.hasErrors()) {

model.addAttribute("error", "Input validation error!");

List<ObjectError> l = result.getAllErrors();

for (ObjectError e : l) {

System.out.println(e.getObjectName() + "-" + e.getCode() + "-" + e.getDefaultMessage());

}

} else {

String message = "Entered user name is " + userFrom.getFirstName()+ " " + userFrom.getLastName();

model.addAttribute("message", message);

}

System.out.println("I am in post" + userFrom.getDateOfBirth());

return "UserBindingView";

}

}

Order of controller method parameters should be Validation bean, BindingResult and then Model object.

View

You can display error messages at View using <f:errors /> tag. Set bean's field name to path attribute and CSS error class to cssClass attribute.

<tr>

<td>ID</td>

<td><f:input path="id" /> <f:errors path="id" cssClass="error" /></td>

</tr>

<tr>

<td>First Name</td>

<td><f:input path="firstName" /> <f:errors path="firstName" cssClass="error" /></td>

</tr>

Configuration

In order enable MVC validation annotation your configuration xml must have following entry

<mvc:annotation-driven />

Maven Dependency

You need to include following Maven dependencies for annotation in pom.xml:

<dependency>

<groupId>javax.validation</groupId>

<artifactId>validation-api</artifactId>

<version>1.1.0.Final</version>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-validator</artifactId>

<version>5.1.0.Final</version>

</dependency>

Annotations

Basic Annotations

    1. @Size(min=2, max=30) will only allow names between 2 and 30 characters long

    2. @NotNull will not allow a null parameter. It checks the name of attribute in the request parameter list, if does not exist then fail validation. By default if parameter is received with empty value then Spring MVC set empty string instead of null to its attribute. For check non empty value then go with @NonEmpty annotation.

    3. @Min(18) will not allow allow value less than 18

    4. @Max(75) will not allow allow value greater than 75

    5. @Pattern(regexp="\\d{6}") will apply a regular expression. Here it will accept 6 digits.

    6. @Digits(integer = 15, fraction = 2) will validate decimal values.

Hibernate Annotations

    1. @NotEmpty : allow non empty string

    2. @Email allow valid email formatted string

    3. @Length (min=3,max=25): checks length of string

    4. @Range: range of a value

    5. @Range(min = 1, max = 150): checks length of a number.

Ex:@Range(min = 1, max = 150) //age need between 1 and 150

int age;

    1. @URL: allow valid URL

Format Annotations

@NumberFormat(style=Style.CURRENCY)

@DateTimeFormat(pattern="MM/dd/yyyy")

Custom Messages (i18n)

You can specify error messages in annotation itself.

@NotEmpty (message="Name is required")

private String name null;

To achieve i18n you can create message_en.properties file can make following entries. You can override default error messages here. Error messages are resolved using the following pattern:

{ValidationClass}.{modelObjectName}.{field}

For example is "password" field of our “loginForm” model object fails the “NotEmpty” validation, the “NotEmpty.loginForm.password" message will be searched.

If message is not found then it will search “NotEmpty.loginForm".

If message is not found then finally it will search “NotEmpty".

If message is not found then default messages will be rendered.

NotEmpty=value can not be empty

Size=Size=value must be between {2} and {1} characters long

Email=Not a valid email.

NotEmpty.form.password=Password is required.

Email.form.emailId=Login should be an email id.