Spring Form Validation

One of the major task in processing form is to validate the form data posted by the user. Though being a very important task it happens to be very tedious. Spring come to some rescue by enabling validation of form data with the help of annotations. We can take advantage of Spring's support for Java Validation API, which would not require any extra configuration. We just need to make sure that we have an implementation of Java Validation API (e.g. Hibernate Validator) in our application classpath.

Java Validation API

The Java Validation API defines certain annotations that are used with Spring to validate beans. Below are some most commonly used annotations:

  • @NotNull - The annotated element must not be null.
  • @NotBlank - The annotated element must not be blank.
  • @Size - Annotated with elements of type String, collection or array, to validate their max-min size.
  • @Max - Annotated with element of number type, to validate their maximum permissible value.
  • @Min - Annotated with element of number type, to validate their minimum permissible value.
  • @Pattern - The annotated element can be validated against a pattern as defined.
  • @Future - Used with date type, to make sure it's in future.
  • @Past - Used with date type, to make sure it's in past.

Validation Annotations in Model Bean

As we know Spring would bind the model fields with the form data (Refer article for details), in order to validate the fields while binding we need to annotate the model field with suitable annotation to help Spring identify what needs to be validated on the fields.

Let's consider a simple User model to capture the data posted by the user from a registration form. Shown below is how we should annotate the fields.

public class User {
    
    @NotBlank(message="First Name cannot be blank")
    private String firstName;
    
    @NotBlank(message="Last Name cannot be blank")
    private String lastName;
    
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date dob;
    
    @Email(message="Invalid Email Id")
    private String email;
    
    @Size(min=6, max=12, message="Password must be between 6 to 12 characters long")
    private String password;
    
    @Min(value=7000000000L, message="Invalid Mobile Number")
    @Max(value=9999999999L, message="Invalid Mobile Number")
    private long mobile;

    --- setters and getters ---
}

The @NotBlank annotation in the firstName and lastName makes sure that they are not left blank, similarly @Size in the password makes sure that its length is between 6 and 12 characters, specified by the min and max attribute respectively. Also the @Min and @Max in the mobile defines the acceptable range of mobile numbers. Similarly the @Email annotation makes sure the email field is a valid email id.

Now that we have annotated the fields for their acceptable values, whenever there is violation of the validation rules, we want the user to know that an invalid value has been entered. For this purpose we would need to show an error message to the user. Notice the message parameter with each of the annotations. This is the same message that will be passed to the front end and displayed to the user upon any validation failure.

Handling Validation in Controller

Before the validation could work, we need to let the controller know which beans to validate. Show below is the controller method to handle the registration form by the user.

@RequestMapping(value="/register", method=RequestMethod.POST)
public String registerUser(@Valid User user, BindingResult results){
    if(results.hasErrors()){
        return "registrationPage";
    }
    userMap.put(user.getEmail(), user);
    return "redirect: profile?email="+user.getEmail();
}

Notice the @Valid annotation to the User parameter. This annotation helps Spring to identify that that User object is needed to be validated. Any validation errors encountered during validation process would be collected in the BindingResult object. This object can be used to check for error (using hasErrors()) as well as to get the individual errors(using getAllErrors()/getFieldErrors()). In our case we send the user back to the registration form if any error comes during validation.


Externalize Validation Message to Property file

We had hardcoded our validation messages in the User fields in the message parameter of the annotation. This is bad coding ethics. It is always advisable to externalise the validation messages to a property file to support internationalization. Shown below is our updated User class.

public class User {
    
    @NotBlank(message="{firstname.invalid}")
    private String firstName;
    
    @NotBlank(message="{lastname.invalid}")
    private String lastName;
    
    @Email(message="{email.invalid}")
    private String email;
    
   --- other fields getter and setters ---
}

Revisit the message parameter in the class above. We have given a string enclosed within curly brackets. This string can be found in the property file, which would contain the actual error message.

All we need to do now is to create the properties file and place in our application classpath. Spring would by default look for a property file named 'ValidationMessages.properties' for the validation message. Shown below is our version of it.

firstname.invalid=First Name must not be blank
lastname.invalid=Last Name must not be blank
email.invalid=Invalid Email Id
password.invalid=Password must be between {min} to {max} characters long
mobile.invalid=Invalid Mobile Number

Displaying Validation Messages in JSP View

If we are using JSP View in our application we can display the validation messages using Spring tags. Spring defines its own tag library which can be used to bind model attributes to html form tags and display errors on validation failure of the model fields.

Shown below is our registration jsp.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%@ page isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
<title>Registration</title>
</head>
<body>
    <h2 style="margin-bottom: 5px;">User Registration</h2>
    
    <sf:form action="register" method="post" commandName="user">
        <div>
            <label>First Name</label>
            <sf:input type="text" path="firstName" />
            <sf:errors path="firstName" cssClass="error" />
        </div>
        <div>
            <label>Last Name</label>
            <sf:input type="text" path="lastName" />
            <sf:errors path="lastName" cssClass="error" />
        </div>
        <div>
            <label>Date of Birth</label>
            <sf:input type="date" path="dob" />
            <sf:errors path="dob" cssClass="error" />
        </div>
        <div>
            <label>Email ID</label>
            <sf:input type="text" path="email"/>
            <sf:errors path="email" cssClass="error" />
        </div>
        <div>
            <label>Password</label>
            <sf:input type="password" path="password"/>
            <sf:errors path="password" cssClass="error" />
        </div>
        <div>
            <label>Mobile</label>
            <sf:input type="text" path="mobile"/>
            <sf:errors path="mobile" cssClass="error" />
        </div>
        <div>
            <input type="submit" value="Submit">
        </div>
    </sf:form>
</body>
</html>

Notice the taglib declaration at the beginning, this is required to used spring form taglib. The sf:form tag has a commandName attribute which is used to bind a model object to the form. The path attribute in the sf:input and sf:errors are the corresponding fields in the model object that the form field should map to. The sf:errors tag would display any validation error corresponding to the mapped model field.

In order to bind the model object to the form it should to passed as model attribute to the view from the controller as shown below:

@RequestMapping("/")
public String showRegistrationPage(Model model){
    model.addAttribute("user", new User());
    return "registrationPage";
}

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