Over a million developers have joined DZone.

No Fuss! No Muss! Implement Validation Using JSR-303 Annotations in Spring

· Integration Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

Every designer and developer knows that user input Validation is a vital part of development for any application. Since the inception of the various MVC frameworks like Struts, Spring, JSF etc., the method of implementing validation has been included in application design considerations. These frameworks set the standards for implementing validation by providing the necessary supporting classes, and certainly, having clean design for validation has its benefits with respect to application maintenance.


Prior to the release of version 3.0 of Spring, validation implementation required that the validator class is registered using a Spring configuration XML file. In addition, developer had to validate the fields and ensure error registration using ValidationUtils in the validate() method of the validator class. After the introduction of annotations in Spring 3.0, implementation of validation was simpler and cleaner. Developers can reduce the code by using the Hibernate Validator framework along with Spring. As of this writing, the latest version of the Hibernate Validator Framework is 5.0, which is the reference implementation of JSR-303). The following illustrates the implementation of constraints and validation using JSR-303 annotations:

JAR Dependencies: You'll need to put the JAR files from Hibernate Validator Framework in the application classpath, which is WEB-INF/lib in a Java Web Project. Hibernate Validator 5.0 ships with a number of various JARs. While some are optional, the following are required JARs for validation implementation.

hibernate-validator-5.1.0.Final

validation-api-1.1.0.Final

classmate-1.0.0

jboss-logging-3.1.3.GA

Annotate model properties: Once you have entered the above JARs in the classpath, you can use the annotations provided by them. The following is an example of a model class where you would need to annotate the properties with required constraints. Note how @Size and @NotEmpty are used.

public class Employee {
private String empId;
private String empName;
@NotEmpty @Size(max = 10)
}
private String designation;

Use of @Valid in controller method argument: To ask Spring to perform the validation on the model fields (based on the constraints we specified), you must use @Valid for the modelattribute in the controller method argument.

Let’s assume that your view has been bound to the EmployeeController using a model attribute named ‘employee’ represented by Employee class. In that case, in addition to @ModelAttribute annotaion, you must annotate the Employee class instance with @Valid. See how it is done in following example:

@Controller

public class EmployeeController {
@RequestMapping(value = "/addEmployee", method=RequestMethod.POST)
public String addEmployee(@ModelAttribute @Valid Employee employee, BindingResult bindingResult) {
if(bindingResult.hasErrors()) { return “employeeForm”; }
}
//Code to add new Employee into the database return “successView”; }

Since we have annotated the modelattribute with @Valid, Spring will perform the validations and register the errors in the BindingResult object.

As shown in the example above, if the bindingResult object contains errors, we show the employee input form again. Otherwise, successView will be displayed. On the JSP page, use the <form:errors> Spring tag to display the errors.

Custom error messages: By default, Spring will show Hibernate Validator’s default error messages (from the Validator Messages properties, which is included in the hibernate-validator-5.1.0.Final jar file) depending on the type of constraint specified. But, often we are required to show custom messages. We can do so by using the “message” parameter of the annotation in the model class. In the following example, for a NotEmpty constraint, we will specify the value of “message” parameter equal to “Employee name cannot be empty".

@NotEmpty(message=”Employee name can not be empty”)
private String empName;

If your application supports internationalization, you can also take the message from the resource file. To accomplish that, the value of the ‘message’ parameter should be the properties file key surrounded by {}. In the example below, the message key is “employee.name.empty”.

@NotEmpty(message=”{employee.name.empty}”)
private String empName;

Here, Spring will try to find the mentioned key in the Hibernate’s default resource files (ValidationMessage.properties). To ask Spring to find the message from your own resource file, you will need the following entry in the Spring configuration XML file (assuming that the Spring bean configuration is done through a configuration XML file).

<mvc:annotation-driven validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFac toryBean">
<property name="validationMessageSource" ref="messageSource" /> </bean>
<property name="basenames" value="com/example/i18n/messages”/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
</bean>

As you can see, we used LocalValidatorFactoryBean to specify our own messageSource implementation. Now, it will read the messages from the messages.properties file, which is the resource file. You should also note that you need to specify the value of the ‘validator’ attribute (which is the bean of the LocalValidatorFactoryBean class) in the <mvc:annotation-drivern> tag.

Simple, right? Follow these steps and you can easily implement validation using the JSR-303 constraint and validation annotations. I think you'll agree that Spring rocks!

Hasan Sunasara: Who loves to design, develop and tune Java Enterprise Applications . I strive to learn new things and improve on every possible areas touched by on the path of life. When not working on Java, I socialize, read blogs and watch movies.

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}