this post will guide you how to validate form data based on the annotations provided in the spring-modules framework.In addition, this will show you how to bind form data to a data model and how to use EL(Expression Language) in Spring web application.
the folllowing technologies have been used to prepare this post.
Spring MVC 3
Maven building tool
Spring Form tag libraries
Intelli J IDEA IDE
SLF4J logging framework
SpringModules Framework for Annotation based data validation
the following diagram shows you the standard directory structure of this sample web application. (it is importnat to note that you are not required to have DAO, Service and Validation sub packages under the org.conver.registration package for this web application. i composed this post and took this screenshot while i was enhancing this simple tutorial to integrate data access using hibernate and JPA. you will get that example in my future post. :) )
now we can see the content of the each file in detailed as follows.
1. web.xml file
Spring3-SpringModules-Annotation based Data Validation-Example index.jsp log4jConfigLocation /resources/log4j.xml registration org.springframework.web.servlet.DispatcherServlet 1 registration / org.springframework.web.context.ContextLoaderListener
In web, XMl you are required to notedown the following points.
*. log4j.xml file configuration for adding logging framework support(either log4j or slf4j for this project)
*.Spring MVC Front Controller Mapping known as MVC dsipatcher servlet
2. the below JSP page represents the user registration view that is displayed to the user for getting the required user inputs.
userRegisterView.jsp file
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <html> <head><title><spring:message code="registration.page.name"/></title> </head> <body> <form:form commandName="user" method="POST" action="register"> <p><spring:message code="registration.form.header"/> </p> <form:label path="username"><spring:message code="registration.label.username"/></form:label> <form:input path="username"/> <form:errors path="username"/> <br/> <form:label path="password"><spring:message code="registration.label.password"/></form:label> <form:password path="password"/> <form:errors path="password"/> <br/> <form:label path="email"><spring:message code="registration.label.email"/></form:label> <form:input path="email"/> <form:errors path="email"/> </br> <input type="submit" value="register" /> </form:form> <spring:message code="registration.page.copyright.information"/> </body> </html>
Important things to note
JSTL tag libraries has been used
spring message binding with external property files
once the user press the register button, it will submit the data using POST method to the relevant controller method that is dedicated for the register URL pattern.In addition, it will bind all the user input for the model object provided as the user in the request scope. you can see the main controller as below.
3. UserAdministration.java file
package org.convey.registration.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.convey.registration.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.Validator; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import java.util.Map; /** * $LastChangedDate: $ * $LastChangedBy: $ * $LastChangedRevision: $ * * Author: Chathuranga Tennakoon ( chathuranga.t@gmail.com tel: 009475961039 ) */ @Controller @RequestMapping("/userRegistration") public class UserAdministration { final static Logger logger = LoggerFactory.getLogger(UserAdministration.class); @Autowired private Validator validator; @RequestMapping(value="/register", method = RequestMethod.GET) public String displayUserRegistrationForm(Map<String, Object> map){ logger.debug(" request is for displaying the user registration form "); //setting up the required value in the request scope for CommandName parameter map.put("user",new User()); // InternalViewResolver will resolve the logical view name to the actual physical views name return "userRegisterView"; } @RequestMapping(value= "/register" , method = RequestMethod.POST) public ModelAndView registerNewUser(@ModelAttribute("user")User user, BindingResult result){ logger.debug(" Form data retrieved from the user registration page and Data validation starts "); String password=user.getPassword(); String username=user.getUsername(); String email=user.getEmail(); //here we are using slf4j for logging logger.debug(" retrieved username is [{}] ",username); ModelAndView view=new ModelAndView("userRegistrationSuccessView"); // the below parameters can be access in userRegistrationSuccessView jsp page using Expression language (EL) view.addObject("password",password); view.addObject("username",username); view.addObject("email",email); validator.validate(user, result); logger.debug(" has form errors? [{}] ",result.hasErrors()); if (result.hasErrors()) { logger.debug(" errors occurred during the validation process "); ModelAndView userRegisterFormView=new ModelAndView("userRegisterView"); return userRegisterFormView; } else{ logger.debug(" all data was properly validated with no errors "); return view; } } }
the below class is the model class called User. you can see that we have used the validation annotations provided in the springmodules framework for validating the user inputs captured from the user interface given above(userRegisterView.jsp)
4.User.java file (data model class)
package org.convey.registration.model; import org.springframework.stereotype.Component; import org.springmodules.validation.bean.conf.loader.annotation.handler.Email; import org.springmodules.validation.bean.conf.loader.annotation.handler.Length; import org.springmodules.validation.bean.conf.loader.annotation.handler.NotBlank; /** * $LastChangedDate: $ * $LastChangedBy: $ * $LastChangedRevision: $ * * Author: Chathuranga Tennakoon ( chathuranga.t@gmail.com tel: 009475961039 ) */ @Component public class User { /* all validation error messages has been defined inside the messages.properties file. */ @NotBlank @Length(min = 5, max = 20) private String username; @NotBlank @Length(min = 5, max = 20) private String password; @NotBlank @Email private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
since we have used @Component annotation for the User class (POJO class), it is not required to define the bean in the xml files. since we have declared
<context:component-scan base-package="org.convey.registration" />
in the xml configuration file, it will automatically discover the classes (that are inside the above package or its sub packages) with the @Component annotations and initiates their instances in the spring web container at the web application loading time.
you can see that we have used spring modules annotations for the user input validation. all the validations messages have been defined inside the messages.properties file. that can be shown as below.
5. messages.properties file
#User Registration From Page registration.page.name=User Registration Page registration.form.header= User Registration Form registration.label.username=Username registration.label.password=Password registration.label.email=Email Address registration.page.copyright.information=Developed by chathuranga.t@gmail.com (tel 0094759610139) #User Registration Form Validation messages User.username[not.blank]=Username is required User.username[length]=Username length should be minimum {1} to maximum {2} Characters. User.username[regexp]=Username can contains only lowercase and uppercase characters User.password[not.blank]=Password is required User.password[length]=Password length should be minimum {1} to maximum {2} Characters. User.email[email]=Invalid characters for the email User.email[not.blank]=Email is required
6. applicationContext.xml file
<?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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- the below bean is configured to define external property file for defining property values for the application. the following bean is used for configuring a resource bundle for this application based on different locales--> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:properties/messages" /> <property name="defaultEncoding" value="UTF-8"/> </bean> </beans>
7.registration-servlet.xml file
<?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:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- this will scan the @Component models defined in the given package (including sub packages) and it will automatically create instances. if you have used @Component annotation, it is not required to define the beans in the XML configuration files --> <!-- Discover POJO @Components --> <context:component-scan base-package="org.convey.registration" /> <import resource="applicationContext.xml"/> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix" value="/WEB-INF/view/" /> <property name="suffix" value=".jsp" /> </bean> <bean id="handlerMappingC" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/userRegistration/*"> userAdministrationController </prop> <prop key="/userRegistration/register/*"> userAdministrationController </prop> </props> </property> </bean> <bean id="userAdministrationController" class="org.convey.registration.controller.UserAdministration"/> <bean id="configurationLoader" class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader"/> <bean id="validator" class="org.springmodules.validation.bean.BeanValidator" p:configurationLoader-ref="configurationLoader"/> </beans>
8. userRegistrationsuccessView.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head><title>User Registration success Page.</title></head> <body> <b>user registration process success</b> <h2>username ${username}</h2> <h2>password ${password}</h2> <h2>email ${email}</h2> </body> </html>
9. pom.xml file
you can access the project through the following link.4.0.0 SpringHibernate hibernate war 1.0 hibernate JBoss repository http://repository.jboss.com/maven2/ maven2-repository.dev.java.net Java.net Repository for Maven http://download.java.net/maven/2/ default UTF-8 3.0.5.RELEASE org.springframework spring-web ${org.springframework.version} org.springframework spring-webmvc ${org.springframework.version} org.slf4j slf4j-log4j12 1.5.6 javax.servlet jstl 1.1.2 taglibs standard 1.1.2 org.springmodules spring-modules-validation 0.9 commons-lang commons-lang 2.3 commons-collections commons-collections 3.1 org.apache.maven.plugins maven-compiler-plugin 1.6 1.6 org.apache.maven.plugins maven-war-plugin 2.0.2 src/main/webapps hibernate
http://localhost:8080/hibername/userRegistration/register
you can download the full source code for the project through the following link.
Download Source
In addition, the source code is available at the following GIT repository.
git@github.com:chathurangat/SpringModules-Annotation-based-Validation.git
once the source is downloaded, you will have to execute the following command in the vi editor for building the project using maven.
maven clean install -DskipTests
once the project is build, copy the hibernate.war file (that is inside the target directory) to the webapps directory of your tomcat server.
regards
Chathuranga Tennakoon
chathuranga.t@gmail.com