This lesson shows how to use the Hibernate Validator with Spring MVC application.

Data validation includes checking if the required fields are not left blank, numbers are within a given range, and data is entered in the correct format. The Standard Bean Validation API is the preferred approach for validation in Spring applications. We will use the Hibernate implementation of the API known as Hibernate Validator.

Hibernate Validator

The current version of Hibernate validator is Hibernate Validator 7.x. Spring 5 is not compatible with this release because of differences in package naming convention. Spring 5 uses Java EE packages starting with javax.* while Hibernate Vaildator 7 has changed package names to jakarta.*.

For this reason, we will use an older version of Hibernate Validator that use the javax.* package naming convention. The validator version that is compatible with Tomcat 7 is version 5.1.3. Newer versions of the validator, 6.2.x, can be used with Tomcat 8 or higher.

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.3.Final</version>
</dependency>

After adding this dependency, we can use the JSR 349 validation annotations.

Validation annotations

Different validation annotations can be used on the fields to validate the data. Hibernate implements the following JSR 349 bean validation annotations:

  • @NotNull checks if a required field is left blank.
  • @Size checks that the input matches a given number of characters or digits.
  • @Min and @Max validate that a number is within a given range.
  • @Past and @Future apply to date fields to check if the date entered is before or after the current date.
  • Regular expressions can be validated using the @Pattern annotation.

Custom validation annotations for business rules of the application can also be created.

In addition to the above mentioned annotations, Hibernate validator also provides additional annotations like @NotEmpty, @NotBlank and @Email etc.

Spring validation support

Spring MVC provides support for different bean validation APIs; JSR 303 (EE6), JSR 349 (EE7), and JSR 380 (EE8). The specifications are backward compatible. We have configured our application to automatically detect and enable validation support.

Recall, from the lesson Configuring a Spring MVC Application - Part 2, where we included the following tag in player-servlet.xml:

<mvc:annotation-driven />

This tag lets Spring MVC detect and enable validation support provided by the bean validation API.

@Vaild annotation

We can validate a model object by using the @Valid annotation in the controller class. When the user clicks the Submit button, the processForm method is executed. The @Valid annotation makes sure that the data entered by the user passes the validation rules.

Data validation takes place before business logic is executed

Spring will first bind the input from the form with the attributes of the model object, then it will validate the object and check for any constraint violations. The BindingResult object contains the results of the validation check.

@RequestMapping("/processPlayerForm")
public static String processForm(@Valid @ModelAttribute("athlete") Athlete myAthlete, 
                                 BindingResult result){

}

An important point to note, is the order of parameters. Spring MVC validation will only work as desired if the BindingResult parameter appears immediately after the @ModelAttribute, else, the validation rules will be ignored.

Inside the method, we will check the validation result. If the result object has any errors, it means that one or more constraints have been violated. In that scenario, we want the user to be sent back to the add-player-form, to fix the errors.

If the result object does not have any errors, then the user can proceed to the player-confirmation page. The hasErrors() method, used in the code below, returns a Boolean value.

public static String processForm(@Valid @ModelAttribute("athlete") Athlete myAthlete, 
                                 BindingResult result) {
    if (result.hasErrors()) 
        return "add-player-form";
    else
    	return "player-confirmation";
}

form:error tag

In the event of a constraint violation, when the user is redirected to the input form, we need a way to inform him about the error. The <form:error> tag displays the error. The path attribute describes the name of the field for which the error message is displayed. For example, to display errors for the lastName field, we can write:

Name: <form:input path = "lastName"/>
<form:errors path="lastName" />

Here, we are telling Spring to display an error message, if it is set. When the form is displayed for the first time, we will not see any error message. The error message will only be displayed when the form is shown after validation constraint violation.

CSS error class

We can define the CSS style for error messages inline in the add-player-form as follows:

<head>
<title>Add Player</title>

<style>
.error {
    color:red;
    font-style: italic;
}
</style>

</head>

The error class defined above, can be referenced in the <form:error> tag:

Name: <form:input path = "lastName"/>
<form:errors path="lastName" cssClass="error"/>

Now, the error messages will be displayed in red color and in italics.

AthleteController.java
Athlete.java
main-menu.jsp
player-confirmation.jsp
add-player-form.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Main Menu</title>
</head>
<body>
<h2> Spring MVC - Tennis Player Database</h2>
<hr><br>
<a href="showPlayerForm"> Search Player</a>
<br><br>
<a href="player/showPlayerForm"> Add Player Details</a>
</body>
</html>