Spring MVC Custom Form Validator

Spring's support for Java Validation API reduces much of the burden of form validation in a Spring MVC application. Validation can be achieved with the help of simple annotations. However there are certain cases where these annotations may not be enough to serve our purpose. We might want to have a certain logic for validating certain field which may not be covered by any other the Java Validation API annotations. For such cases we can create our own custom form validator and use it validate the required fields.


Validator Interface

Spring provides the org.springframework.validation.Validator interface, which must be implemented by every form validator that is supposed to be used in a Spring MVC application. So, in order to create a custom for validator first thing we need to do is to implement the Validator interface. This interface declares two methods:

  • public boolean supports(Class<?> clazz): This method should return true if it can validate an instance of the supplied class in the parameter.
  • public void validate(Object target, Errors errors): This method is where we need to write our validation logic. The target param is the object to be validated and the errors object contains the state of the validation process.

Custom Form Validator

To demonstrate the custom form validator let's consider a simple scenario of user registration. Before we register any user to our application we want to check if the user is 18 years of age. We display a simple form where the user enters his/her name, email, password and date of birth. We need to make sure that the user must be 18 years of age to be able to successfully register into the application.

We would only be discussing the custom form validator in this article. However you can download the complete application at the end of this tutorial. To know details of Spring OOTB form validation check this article.

The custom validator is shown below:

@Component
public class UserValidator implements Validator{

    public boolean supports(Class<?> arg0) {
        return User.class.isAssignableFrom(arg0);
    }

    public void validate(Object target, Errors errors) {
        User user = (User) target;
        Date dob = user.getDob();
        Calendar birthDate = Calendar.getInstance();
        Calendar currDate = Calendar.getInstance();
        currDate.setTime(new Date());
        birthDate.setTime(dob);
        birthDate.add(Calendar.YEAR, 18);
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "dob", "dob.invalid.empty");
        
        if(birthDate.after(currDate)){
            errors.rejectValue("dob", "dob.less.18");
        }
    } 
}

First thing we need to do is to define our custom form validator as a Spring bean, hence the @Component annotation.

Notice the use of isAssignableForm(). This is a method of the Java Class class. It returns true if the supplied class can be assigned to the invoking class object. This would happen when the supplied class in param is either object of the invoking class or its child.

Our validation logic goes in the validate method. We calculate the user's age based of the supplied date of birth and throw and reject the value if the age happens to be less than 18 years. In our example we have used the Spring's ValidationUtils.rejectIfEmptyorWhitespace() method to check for empty values. The 1st parameter to this method is the errors object, which is the contextual object used to store validation errors. The 2nd param is the form field/ model property name, which we are validation. The third param is the key for the validation message which is stored in the resource bundle (properties file).

The entries in the properties file looks as shown below:

dob.less.18=User must be more than 18 years.
dob.invalid.empty=DOB can't be blank

For Spring to know where to look for the properties file we need to load the properties file as a message resource. This can be done by defining a message resource bean in the spring config file as shown below:

<bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:ValidationMessages" />
</bean>

Here ValidationMessages.properties is the name of our properties file. It should be placed in the application classpath.


Download Source Code

You can download the source code of the Sample Spring Application discussed in this article.

POPULAR ARTICLES

Creating Conditional Beans in Spring

The concept of condition beans enables Spring to restrict the creation of any bean depending on the evaluation of a condition. These beans get created only when a preset condition is evaluated as true

View Article

Accepting Request Param and Path Variable in Spring Controller

Spring MVC provides various ways through which a client browser can pass data to the Controller. In this article we will discuss about accepting Request Parameters and Path Variables in Spring Contr..

View Article

Generate Namespace & Schema Information using JAXB

Most xml documents used in enterprise applications makes use of namespace to avoid element name conflicts. This article talks about generating these namespace and schema information when marshaling...

View Article

Switching Database Profile using Spring Profiles

We are most likely to have separate db configuration for different environment like development and production environment. Spring profiles provide a convenient way to switch db profiles at runtime.

View Article

SQL and its Sub-Languages

SQL (Structured Query Language) is a language understood by most modern databases. It is an ANSI (American National Standard Institute) standard language which is used to manipulate databases.

View Article

Introducing JUnit Rule

Junit Rules allows developers to add additional functionalities that can applied to all test methods in a test class. It is similar to the concept of custom test runners but with reduced restrictions.

View Article

Addressing Ambiguity in Spring Autowiring

Spring autowiring is powerful concept, but we should be very cautious while using it. We may end up in creating ambiguity while autowiring beans, which will cause autowiring to fail.

View Article

Creating and Using Synonym in Oracle Database

Synonyms are database objects used to provide duplicate names to existing objects in the database. It is just an alternate name used to hide the original name of the object.

View Article

Creating and Using Sequence in Oracle Database

A sequence is used to auto-generate numbers in ascending or descending order which can serve as a primary key or a part of it (in case of composite key).

View Article

Creating and Manipulating Constraints in Oracle Database

Constraints are used to impose certain rules on columns to avoid invalid data entry into the table. If any of the constraint is violated the operation fails.

View Article

Integrating Log4J with Perf4J for Performance Logging

Perf4j is an open source logging framework used primarily for monitoring performance statistics in java applications. Log4j has the ability to integrate with perf4j to capture performance data.

View Article

Tagging in GIT

Tagging allows us to mark a specific point in the commit history or snapshot. A tag is typically used to mark a project release. This article shows how to create tags in Git.

View Article