Interview Questions

Spring Validation

In this article, we will be discussing about Validation in Spring framework. In any web application, we will be often faced with a requirement to validate the fields in user interface(UI). There are basically two types of validation

1. Client side validation
2. Server side validation

Client side validation is usually done using Java Script. Server side validation is usually provided by the MVC framework. Frameworks such as Spring and Struts provide support for validation.

Now lets see, how to do simple validation using Spring.

Consider a simple application containing a page of three fields (name, age and email). Lets validate these three fields using the validator interface available in Spring framework. Have a look at the JSP file containing the fields.

InputPage.jsp

<%@ page contentType="text/html;charset=UTF-8" %>  
<%@ page pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<fmt:setBundle basename="messages"/>

<html>

<head>
      <title> Validation Demo - TechDive.in</title>
</head>

<body>
<h1>Validation Demo - TechDive.in - Main Form</h1>

<form:form method="post" commandName="cmdData">

    <p>Enter Name : <form:input path="name"/></p>
    <h2><font color="#2c770b"><form:errors path="name" /></font></h2>

    <p> Age : <form:input path="age"/></p>
    <h2><font color="#2c770b"><form:errors path="age" /></font></h2>

    <p> Email : <form:input path="email"/></p>
    <h2><font color="#2c770b"><form:errors path="email" /></font></h2>

    <input type="submit" value="Submit">

</form:form>

</body>

</html>

Note that after every field there is
tag which is used to display the error message corresponding to the field, if any. The error message is sent from the server side after validation.

Take a look at the validator class which implements the validator interface in Spring.

package in.techdive.spring.example;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class Techdive_Validator implements Validator
{
        public boolean supports(Class arg0)
        {
                return Entity.class.isAssignableFrom(arg0);
        }

        public void validate(Object target, Errors errors)
        {
                /*
                 * Here, the 2nd argument "name" is the field of the bean "Entity"
                 */

                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name",

                /* error_empty_value is the Key in Bundle Properties which is used to fetch data from Bundle Properties */
                "error_empty_value",

                /* Default Message for Display if Key not found in Bundle Properties */
                "Enter Name (Data coming Directly from Server)");

                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "age",
                                "error_empty_value",
                                "Enter Name (Data coming Directly from Server)");

                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email",
                                "error_empty_value",
                                "Enter Name (Data coming Directly from Server)");

                Entity e = (Entity) target;
                if (e.getAge() < 0)
                {
                        errors.rejectValue("age", "error_negative_age");
                }
                else if (e.getAge() > 110)
                {
                        errors.rejectValue("age", "error_too_large_age");
                }

                Pattern p = Pattern.compile(".+@.+\\.[a-z]+");

                Matcher m = p.matcher(e.getEmail());

                //check  whether any match is found
                boolean matchFound = m.matches();

                if (!matchFound)
                {
                        errors.rejectValue("email", "error_invalid_email");
                }
        }
}

There are two methods in Validator Interface,
1. supports(Class arg0) - used to check whether the validator supports the validation for the provided bean
2. validate(Object target, Errors errors) - contains the target bean and the Errors object. This method should be implemented to validate the target bean fields and register an error if any in the Errors object.

The validate method here first checks for null or empty fields and returns the error message. Then it checks for validity of age (0 <= age <=110 ). It also checks for the format of the email entered in the field.

The error messages are specified in the messages.properties file as follows.

messages.properties

error_empty_value=Error: Empty Value
error_negative_age=Error: Age should not be Negative
error_too_large_age=Error: Age should be less than 110
error_invalid_email=Error: Email is invalid

Now lets see the Spring bean configuration file, which contains the beans for controller, ReloadableResourceBundle and InternalViewResolver etc.,

springdemo-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- messageSource used to load Bundle Properties inorder to display Validation Error Messages -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
</bean>
<!-- Validator Class definition -->
<bean id="validator" class="in.techdive.spring.example.Techdive_Validator" />
<!-- Main Controller Class definition -->
<bean name="/demo.htm" class="in.techdive.spring.example.Techdive_Controller">
<property name="sessionForm" value="true"/>
<property name="commandName" value="cmdData"/>
<property name="commandClass" value="in.techdive.spring.example.Entity"/>
<property name="validator"><ref local="validator"/></property>
<property name="formView" value="InputPage"/>
<property name="successView" value="InputPage"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>

The in.techdive.spring.example.Techdive_Controller is a Simple Form Controller, in which we inject our Techdive_Validator class to take care of validation. Whenever the submit button is clicked in the UI page, the control goes to the Techdive_Controller.

First it calls the validate method in Techdive_Validator. If there are any errors then the control goes to the same JSP page with the errors. Else the control goes to the success page.

Here is the Techdive_Controller class file.

package in.techdive.spring.example;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

public class Techdive_Controller extends SimpleFormController
{

        protected Map referenceData(HttpServletRequest request, Object command,
                        Errors errors) throws Exception
        {
                return new HashMap();
        }

        public ModelAndView onSubmit(Object command) throws ServletException
        {
                String name = ((Entity) command).getName();

                Map<String, Object> map = new HashMap<String, Object>();
                map.put("name", name);
                map.put("age", ((Entity) command).getAge());
                map.put("email", ((Entity) command).getEmail());

                return new ModelAndView("OutputPage", "model", map);
        }

}

Here is the success JSP page, which is displayed when there are no errors in the fields.

OutputPage.jsp

<%@ page contentType="text/html;charset=UTF-8" %>  
<%@ page pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>

<head>
      <title> Validation Demo - TechDive.in</title>
</head>

<body>

<h1>Validation Demo - TechDive.in - Response Form</h1>
    <p>Name from Server = <c:out value="${model.name}" /></p>
    <p>Age from Server = <c:out value="${model.age}" /></p>
    <p>Email from Server = <c:out value="${model.email}" /></p>
</body>

</html>

In this way, we can use the Validation framework in Spring.