14 June 2015

Introduction

In most of the application there are java script based front end validation. Sometimes there are business needs to have the same validation in front end and server side as well to make the system full proof from security threat. In this tutorial I am going to show how to implement server side validation using Spring MVC and Hibernate validator framework.
This is simple 2 pages application. In the first page it is going to validate and accept Student Name, Age and Id and in the second page it will display the Name, Age and Id.

Required Software

  • Eclipse for J2EE
  • JDK 1.7
  • Maven 2.2.x or above
  • Tomcat 7

Steps to write code

The project structure and important file details are given below

SL No File Name Description
1 WEB-INF/applicationContext.xml This file has annotation-driven, component-scan and InternalResourceViewResolver configurations. annotation-driven configuration is must for the annotation driven validation
2 com.ashish.beans.Student age, name and id properties are declared and validation annotation added against each property
3 com.ashish.controller.StudentController Controller to display two different screens. User input validation is done in this class
4 WEB-INF/jsp/student.jsp Screen to take name, age and id as input from user. Validation errors are displayed in this same screen
5 WEB-INF/jsp/result.jsp Displays user’s valid input in this screen
  • Create a maven project and update the pom.xml with the below content
 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.ashish.spring</groupId>
	<artifactId>SpringMVCValidation</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<spring.version>3.0.5.RELEASE</spring.version>
	</properties>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<!-- Spring 3 dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- Need Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.1.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.0.1.Final</version>
		</dependency>
	</dependencies>
</project>
  • WEB-INF/applicationContext.xml has annotation-driven, component-scan and InternalResourceViewResolver configurations. annotation-driven configuration is must for the annotation driven validation
 
<?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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  	
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<!-- This configuraton is must for the annotation driven validation -->
	<mvc:annotation-driven />
	<context:component-scan base-package="com.ashish" />
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="WEB-INF/jsp/" />
      	<property name="suffix" value=".jsp" />
	</bean>

</beans>
  • Create Student.java bean to bind data between jsp and controller
 
package com.ashish.beans;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

public class Student {
	@NotNull(message="Please enter your age")
	@Min(value=1, message="Age should be between 1-30")
	@Max(value=30, message="Age should be between 1-30")
	private int age;
	
	@NotEmpty(message="Please enter your name")
	@Size(min=1,max=40,message="Name should not exceed 40 character long")
	private String name;

	@NotNull(message="Please enter your id")
	@Min(value=100, message="Id should be 3 digits long")
	@Max(value=999, message="Id should be 3 digits long")
	private int id;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}
  • StudentController.java: Controler to choose valid screen for the user. The user input is validated in this controller class. Http Request handling also shown in this controller. Go through the java doc comments for better understanding
 
package com.ashish.controller;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.ashish.beans.Student;

@Controller
public class StudentController {

	/**
	 * The request mapping will work for two different URLs
	 * @param mm
	 * @return
	 */
	@RequestMapping({"/*", "/student"})
	public String student(ModelMap mm) {
		// Bind Student object with model attribute called "student" (refer student.jsp file)
		mm.addAttribute("student", new Student());
		return "student";
	}

	/**
	 * This method validates the user input and displays the right jsp to the user.
	 * Note that BindingResult must follow @ModelAttribute
	 * In this method Http request handling also shown (HttpServletRequest has been used as method parameter)
	 * @param student
	 * @param errors
	 * @param model
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/addStudent", method = RequestMethod.POST)
	public ModelAndView addStudent(@Valid @ModelAttribute("student") Student student, BindingResult errors, ModelMap model, HttpServletRequest req) {
		
		// If the form has error then it will render user the input screen
		if (errors.hasErrors()) {
			return new ModelAndView("student", "student", model);
		}
		
		// Populating model from http request and Student object
		model.addAttribute("name", req.getParameter("name"));
		model.addAttribute("age", student.getAge());
		model.addAttribute("id", student.getId());
		return new ModelAndView("result", "student", model);
	}
}

  • student.jsp for user input. It also displays the validation error (if any)
 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head></head>
<body>
	<h2>Student Information</h2>
	<form:form method="POST" action="addStudent" modelAttribute="student">
		<table>
			<tr>
				<td><form:label path="name">Name: </form:label></td>
				<td><form:input path="name" /></td>
				<td><span style="color:red;"><form:errors path="name"/></span></td>
			</tr>
			<tr>
				<td><form:label path="age">Age: </form:label></td>
				<td><form:input path="age" /></td>
				<td><span style="color:red;"><form:errors path="age"/></span></td>
			</tr>
			<tr>
				<td><form:label path="id">Id: </form:label></td>
				<td><form:input path="id" /></td>
				<td><span style="color:red;"><form:errors path="id"/></span></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="Submit" /></td>
			</tr>
		</table>
	</form:form>
</body>
</html>
  • result.jsp It displays valid user data
 
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
    <title>Spring MVC Form Handling</title>
</head>
<body>

<h2>Submitted Student Information</h2>
   <table>
    <tr>
        <td>Name: </td>
        <td>${name}</td>
    </tr>
    <tr>
        <td>Age: </td>
        <td>${age}</td>
    </tr>
    <tr>
        <td>Id: </td>
        <td>${id}</td>
    </tr>
</table>  
</body>
</html>

Output

Below is the output of the application. The first screen is the default input screen. 2nd screen shows validation error and 3rd screen shows the user’s valid input



blog comments powered by Disqus
J2EE,SOAP,RESTful,SVN,PMD,SONAR,JaCoCo,HTTP,API,MAVEN,AngularJS,GitHub,LDAP,AOP,ORM,JMS,MVC,AWS,SQL,PHP,H2DB,JDBC