Spring MVC Bean Validator

In this example, I will show you how to build a bean validator for User model object.In my previous example, Spring MVC Custom Validator, I have shown how to validate user input.

Validating input received from the user to maintain data integrity is an important part of application logic.

The Bean Validation model is supported by constraints in the form of annotations placed on a field, method, or class of a JavaBeans component, such as a managed bean.

Constraints can be built in or user defined. User-defined constraints are called custom constraints. Several built-in constraints are available in the javax.validation.constraints package. You can read more on bean validation JavaBeans Validation

Now I will move to the actual example.
Prerequisites
The following configurations are required in order to run the application
Eclipse Kepler
JDK 1.8
Tomcat 8
Have maven 3 installed and configured
Spring 4 dependencies in pom.xml
Now we will see the below steps how to create a maven based project in Eclipse
Step 1. Create a maven based web project in Eclipse

Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.

maven-arctype-webapp
Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : spring-mvc
Step 2. Modify the pom.xml file as shown below.

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.roytuts</groupId>
	<artifactId>spring-mvc</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-mvc Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<java.version>1.8</java.version>
		<spring.version>4.3.0.RELEASE</spring.version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
			<scope>provided</scope>
		</dependency>
		<!-- jstl -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
                <!-- JSR 303 Dependencies -->
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.3.1.Final</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>spring-mvc</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Step 3. Now modify the web.xml file with below source code

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
	<!-- dispatcher servlet acts as a front controller for each request/response -->
	<servlet>
		<servlet-name>spring-mvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- load Spring controllers while dispatcher servlet loads -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:controllers.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- map URL suffix as .html -->
	<servlet-mapping>
		<servlet-name>spring-mvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

Step 4. Create controllers.xml file under src/main/resources directory with the below source code

<?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"
	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">
	<!-- Scan the package where Spring Controllers are placed -->
	<context:component-scan base-package="com.roytuts.spring.mvc" />
	<!-- Resolves logical String-based view names to actual View types -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<!-- Where pages are kept -->
		<property name="prefix" value="/pages/" />
		<!-- What is the page extension -->
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

In above configuration file I have used <context:component-scan/> to register the @Component classes as Spring beans in the base package com.roytuts.spring.mvc and when a class is annotated with @Component then we do not need to register the class in the XML configuration to make it registered explicitly.

Step 5. Create a directory called pages under webapp directory for putting jsp views.

Step 6. Create below User model class. In this class you will see how I have used annotations on fields or attributes of the class to validate user inputs.

package com.roytuts.spring.mvc.models;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
public class User {
	@Size(min = 3, max = 25)
	private String name;
	@Pattern(regexp = ".+@.+\.[a-z]+", message = "Example, contact@roytuts.com")
	private String email;
	@Size(min = 10, max = 250)
	private String address;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
}

Step 7. Create Spring controller class which will handle user request and response

package com.roytuts.spring.mvc.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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 com.roytuts.spring.mvc.models.User;
import com.roytuts.spring.mvc.validators.UserValidator;
@Component
@Controller
@RequestMapping("/register")
public class UserController {
	// JSR-303 validator
	private Validator validator;
	public UserController() {
		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
		validator = factory.getValidator();
	}
	@RequestMapping(method = RequestMethod.GET)
	public String setupUserForm(Model model) {
		User user = new User();
		model.addAttribute("userForm", user);
		return "add";
	}
	@RequestMapping(method = RequestMethod.POST)
	public String submitUserForm(@ModelAttribute("userForm") User user, BindingResult result, Model model) {
		// JSR-303 validation
		Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
		for (ConstraintViolation<User> constraintViolation : constraintViolations) {
			String propertyPath = constraintViolation.getPropertyPath().toString();
			String message = constraintViolation.getMessage();
			result.addError(new FieldError("userForm", propertyPath, "Invalid " + propertyPath + " (" + message + ")"));
		}
		if (result.hasErrors()) {
			return "add";
		}
		// save the object user to some persistent storage
		// return to the success page
		model.addAttribute("success", "User successfully saved");
		return "success";
	}
}

Step 8. Create below add.jsp page and put it under webapp/pages directory. In the below jsp page I have used Spring framework’s tag library for using in the form. Also notice <form:errors path="*" cssClass="error" /> is used for showing all errors in the same place in a form instead of individual errors.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<title>Spring MVC Validator Example</title>
<head>
<style>
.error {
	color: #ff0000;
	font-weight: bold;
}
</style>
</head>
<body>
	<h2>Spring MVC Validator Example</h2>
	<div>&nbsp;</div>
	<form:form action="register" method="post" commandName="userForm">
                <form:errors path="*" cssClass="error" />
                <div>&nbsp;</div>
		Name: <form:input path="name" /><form:errors path="name" cssClass="error" />
		<br />
		<br /> Email: <form:input path="email" /><form:errors path="email" cssClass="error" />
		<br />
		<br /> Address:<form:textarea path="address" rows="5" cols="30" /><form:errors path="address" cssClass="error" />
		<br />
		<input value="Add User" type="submit" />
	</form:form>
</body>
</html>

Step 9. Create below success.jsp page and put it under webapp/pages directory

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<html>
<title>Spring MVC Validator Example</title>
<body>
	<h2>Spring MVC Validator Example</h2>
	<p>${success}</p>
</body>
</html>

Step 10. Deploy the application and hit the URL http://localhost:8080/spring-mvc/register. When you do not fill up the form and click on Add User button.


spring mvc bean validator

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *