Spring Validation in the Web Tier
In the final section of the article, we will see how Spring validation can be used on the Web tier. Note that the functionality of the sample application will be kept minimal as the concentration is on validation usage only. We will build a simple Customer details form which we prompt for various customer details for registration. All the fields are mandatory, hence if the user didn’t enter a value for any of the fields, appropriate error messages will be thrown.
Have a look at the web.xml file where we define the Spring’s dispatcher servlet. Note that the presence of this servlet will load the application context present in the file ‘application-Context.xml’ present in the ‘WEB-INF’ directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>SpringExample8</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>main.jsp</welcome-file>
</welcome-file-list>
</web-app> |
Here is the complete code listing of the file ‘applicationContext.xml’. We have defined JSP as views and they will be searched under the directory ‘/WEB-INF’. We will look into the definition of the validator class and the service class soon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/" p:suffix=".jsp" />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="customer_error_messages" />
<bean id="customerDetailService" class="net.javabeat.articles.spring.validation.cdf.service.CustomerDetailServiceImpl" />
<bean id="customerDetailValidator" class="net.javabeat.articles.spring.validation.cdf.validator.CustomerDetailValidator" />
<bean name="/customerDetailForm.htm" class="net.javabeat.articles.spring.validation.cdf.controller.CustomerDetailController"
p:customerDetailService-ref="customerDetailService" p:formView="customerDetailForm"
p:successView="customerDetailSuccess" p:validator-ref="customerDetailValidator" />
</beans> |
Have a look at the mapping for the entry ‘customerDetailForm’ to the controller ‘CustomerDetailCustomer’. We have also mapped the ‘customer-validator’ to this controller in the bean definition.
This jsp page provides a decoration for prompting the user for inputs. We have made use of Spring form tags, which provides a greater flexibility in mapping the form details directly to a command object. Note that we have used ‘form:input’ tag for mapping the field directly to the command object and ‘form:error’ for populating the error messages in case of any errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<title>Customer Detail Form Page</title>
<style>
.customer_error{
color: #ff0000;
font-style: italic;
}</style>
</head>
<body>
<form:form method="POST" commandName="customerDetail">
<table align="center" border="2">
<tr>
<td>Customer Name:</td>
<td><form:input path="name" /></td>
<td><form:errors path="name" cssClass="customer_error" /></td>
</tr>
<tr>
<td>Customer Address:</td>
<td><form:password path="address" /></td>
<td><form:errors path="address" cssClass="customer_error" /></td>
</tr>
<tr>
<td>Email Id:</td>
<td><form:password path="emailId" /></td>
<td><form:errors path="emailId" cssClass="customer_error" /></td>
</tr>
<tr>
<td>Phone Number:</td>
<td><form:password path="phoneNumber" /></td>
<td><form:errors path="phoneNumber" cssClass="customer_error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Register Customer"></td>
</tr>
</table>
</form:form>
</body>
</html> |
Here is the definition of the ‘CustomerDetail’ model object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package net.javabeat.articles.spring.validation.cdf.model;
public class CustomerDetail {
private String name;
private String address;
private String emailId;
private String phoneNumber;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
} |
The definition is pretty simple – it has properties like ‘name’, ‘address’, ‘emailId’ and ‘phoneNumber’ which needs to be validated.
1 2 3 4 5 6 7 8 | package net.javabeat.articles.spring.validation.cdf.service;
import net.javabeat.articles.spring.validation.cdf.model.CustomerDetail;
public interface CustomerDetailService {
void addCustomerDetail(CustomerDetail customerDetail);
} |
The definition of the customer service object is given below. The method ‘addCustomerDetail’ is exposed which can be invoked as part of registration. The implementation for the above service object is given below. The implementation stores all the customer details in a set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package net.javabeat.articles.spring.validation.cdf.service;
import java.util.HashSet;
import java.util.Set;
import net.javabeat.articles.spring.validation.cdf.model.CustomerDetail;
public class CustomerDetailServiceImpl implements CustomerDetailService{
private Set<CustomerDetail> customerDetails;
public CustomerDetailServiceImpl(){
customerDetails = new HashSet<CustomerDetail>();
}
public void addCustomerDetail(CustomerDetail customerDetail) {
customerDetails.add(customerDetail);
}
} |
The validator class that does the validation on the customer object is provided. In case of any error scenarios, the error object is populated and the error information will be mapped to the property file with the base name ‘customer_error_messages’ as that is how we have configured the bean definition in the dispatcher servlet. Rest of the files are omitted, however they are included and available in the download.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package net.javabeat.articles.spring.validation.cdf.validator;
import net.javabeat.articles.spring.validation.cdf.model.CustomerDetail;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class CustomerDetailValidator implements Validator{
public boolean supports(Class<?> classObject) {
return classObject == CustomerDetail.class;
}
public void validate(Object bean, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "customer.name.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "address", "customer.address.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "emailId", "customer.emailId.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "phoneNumber", "customer.phoneNumber.required");
}
} |
Run the application and click the ‘Register’ button without providing any data in the form. It can be noticed that the validator would have got invoked and the validation error codes are appropriately mapped to the error messages and they will get displayed in the UI.
Conclusion
This article provides plenty of code samples to get a better understanding on Spring validators. Hope the readers would have gained information on Spring’s validator API and the supporting classes and can use them at appropriate instances.







March 1, 2011
Spring Framework