Spring MVC form validation with Java Validation API

Tools and Technologies used
1)Eclipse IDE Mars Release (4.5.0)
2)Java 8
3)Spring framework 4.2
4)Tomcat 8
5)Validation API

In spring MVC , we can validate the form in many ways , we can use validation API ,custom validator or directly validating in controller after the form submit.

Lets see how we can do the same using Java Validation API.

Java Validation API suggests us to use annotation on the model class for each attribute to specify the validation constraints.

Example:

1
2
3
4
5
6
7
8
9
10
11
public class Customer {
    
    @NotNull
    @Email
    private String emailId;
    
    @NotNull
    @Size(min=8,max=15)
    private String password;
//getters  and setters
}
public class Customer {
	
	@NotNull
	@Email
	private String emailId;
	
	@NotNull
	@Size(min=8,max=15)
	private String password;
//getters  and setters
}

So we are using @NotNull to specify that emailId and password fields should not be null.

@Email – specifies that , emailId field is getting validated as per the email standard provided by Hibernate validator.

@Size specifies that password field should be minimum of 8 characters and maximum of 15 characters.

We can use many other annotations to validate the fields in the form.

In the controller class, specify the form backing model object with @Valid annotation to ensure that form values gets binded with this model object and do the validation.

1
2
3
4
5
6
7
8
9
@Controller
public class LoginController {
    
     @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
        public String doLogin(@Valid User user, BindingResult result) {
            // login logic here
        }
 
}
@Controller
public class LoginController {
	
	 @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
	    public String doLogin(@Valid User user, BindingResult result) {
	        // login logic here
	    }

}

If any validation error occurs as per our validation defined in the model class, then BindingResult will have the errors.

1
2
3
4
5
6
7
8
if (result.hasErrors()) {
 
    // form validation error, return the same form
 
} else {
 
    // form input is fine, continue the flow
}
if (result.hasErrors()) {
 
    // form validation error, return the same form
 
} else {
 
    // form input is fine, continue the flow
}

so we can check the binding results for any errors.
If it has errors we can return the same form with error message, if not we can continue the flow.

We can display the error messages on the jsp by using spring’s form errors tag as follows

1
<form:errors path="emailId" />
<form:errors path="emailId" />

Where emailId is the exact attribute name in the Customer Model class.

We can also specify the error message while specifying the validation constraints in the model class with annotation as below

1
2
@NotEmpty(message = "Email Id is Required.")
private String emailId;
@NotEmpty(message = "Email Id is Required.")
private String emailId;

since error message has to be localized, we will specify it in the properties file.

The way of specifying the key in the properties file is

1
ConstraintName.modelAttributeName.propertyName=validation error message
ConstraintName.modelAttributeName.propertyName=validation error message

Example

1
NotEmpty.customer.emailId=Email Id is Required.
NotEmpty.customer.emailId=Email Id is Required.

Lets see full example

Project structure is as below


Create the Model class as below

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
package com.kb.model;
 
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
 
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
 
public class Customer {
    
    @NotNull
    @NotEmpty
    @Email
    private String emailId;
    
    @NotNull
    @Size(min=8,max=15)
    private String password;
 
    public String getEmailId() {
        return emailId;
    }
 
    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
}
package com.kb.model;

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

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

public class Customer {
	
	@NotNull
	@NotEmpty
	@Email
	private String emailId;
	
	@NotNull
	@Size(min=8,max=15)
	private String password;

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

Create the login jsp page as below

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
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Spring MVC form Validation</title>
</head>
 
<body>
    <h2>Enter below details to login</h2>
 
    <form:form method="POST" modelAttribute="customer" action="doLogin">
        <table>
            
            <tr>
                <td>Enter your E-mail:</td>
                <td><form:input path="emailId" /></td>
                <td><form:errors path="emailId" cssStyle="color: #ff0000;" /></td>
            </tr>
            
            <tr>
                <td>Enter a password:</td>
                <td><form:password path="password"  showPassword="true"/></td>
                <td><form:errors path="password" cssStyle="color: #ff0000;"/></td>
            </tr>
            
            <tr>
                <td><input type="submit" name="submit" value="Register"></td>
            </tr>
        </table>
    </form:form>
 
</body>
</html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Spring MVC form Validation</title>
</head>

<body>
	<h2>Enter below details to login</h2>

	<form:form method="POST" modelAttribute="customer" action="doLogin">
		<table>
			
			<tr>
				<td>Enter your E-mail:</td>
				<td><form:input path="emailId" /></td>
				<td><form:errors path="emailId" cssStyle="color: #ff0000;" /></td>
			</tr>
			
			<tr>
				<td>Enter a password:</td>
				<td><form:password path="password"  showPassword="true"/></td>
				<td><form:errors path="password" cssStyle="color: #ff0000;"/></td>
			</tr>
			
			<tr>
				<td><input type="submit" name="submit" value="Register"></td>
			</tr>
		</table>
	</form:form>

</body>
</html>

Create the login home jsp page as below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
 <div align="center">
        <h2>Welcome ${customer.emailId}! You have logged in successfully.</h2>
  </div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
 <div align="center">
        <h2>Welcome ${customer.emailId}! You have logged in successfully.</h2>
  </div>
</body>
</html>

Create the controller class as below

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 com.kb.controller;
 
import javax.validation.Valid;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
import com.kb.model.Customer;
 
@Controller
public class LoginController {
    
    
     @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String viewLoginPage(Model model) {
          Customer customer = new Customer();
            model.addAttribute("customer", customer);
            return "login";
        }
    
     @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
        public String doLogin(@Valid Customer customer, BindingResult result,Model model) {
         model.addAttribute("customer",customer);
          if(result.hasErrors()){
              return "login";
          }
          
          return "home";
        }
 
}
package com.kb.controller;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.kb.model.Customer;

@Controller
public class LoginController {
	
	
	 @RequestMapping(value = "/login", method = RequestMethod.GET)
	    public String viewLoginPage(Model model) {
	      Customer customer = new Customer();
	        model.addAttribute("customer", customer);
	        return "login";
	    }
	
	 @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
	    public String doLogin(@Valid Customer customer, BindingResult result,Model model) {
		 model.addAttribute("customer",customer);
	      if(result.hasErrors()){
	    	  return "login";
	      }
	      
	      return "home";
	    }

}

Create the spring mvc configuraton file

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
<?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"
    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.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
 
    <context:component-scan base-package="com.kb.*" />
    <mvc:annotation-driven />
 
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>
 
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
 
        <property name="basename" value="/WEB-INF/messages" />
    </bean>
</beans>
<?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"
	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.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

	<context:component-scan base-package="com.kb.*" />
	<mvc:annotation-driven />

	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/pages/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<bean id="messageSource"
		class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

		<property name="basename" value="/WEB-INF/messages" />
	</bean>
</beans>

Create the web.xml as below

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
<web-app 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"
    version="3.1">
 
    <display-name>Spring MVC Form Validation-Bean-API</display-name>
 
    <!-- Spring MVC dispatcher servlet -->
    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
            /WEB-INF/spring-mvc.xml,
        </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- Loads Spring Security configuration file -->
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-mvc.xml,
        </param-value>
    </context-param>
</web-app>
<web-app 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"
	version="3.1">

	<display-name>Spring MVC Form Validation-Bean-API</display-name>

	<!-- Spring MVC dispatcher servlet -->
	<servlet>
		<servlet-name>mvc-dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
			/WEB-INF/spring-mvc.xml,
		</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>mvc-dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Loads Spring Security configuration file -->
	 <context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-mvc.xml,
		</param-value>
	</context-param>
</web-app>

Create the pom.xml as below

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<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>Spring</groupId>
  <artifactId>Spring-form-validation</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Spring-form-validation Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
        <org.springframework.version>4.2.0.RELEASE</org.springframework.version>
    </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</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>
  <build>
    <finalName>SpringMVCFormValidationBeanValidator</finalName>
    <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
  </build>
</project>
<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>Spring</groupId>
  <artifactId>Spring-form-validation</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Spring-form-validation Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
		<org.springframework.version>4.2.0.RELEASE</org.springframework.version>
	</properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
	<groupId>javax.servlet.jsp.jstl</groupId>
	<artifactId>javax.servlet.jsp.jstl-api</artifactId>
	<version>1.2.1</version>
</dependency>
<dependency>
	<groupId>taglibs</groupId>
	<artifactId>standard</artifactId>
	<version>1.1.2</version>
</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>
  <build>
    <finalName>SpringMVCFormValidationBeanValidator</finalName>
    <plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
  </build>
</project>

Create the messages.properties file as below inside WEB-INF folder

1
2
3
4
NotEmpty.customer.emailId=Email Id is required. 
Email.customer.emailId=valid email id is required.
NotEmpty.customer.password=Password is required.
Size.customer.password=Password should be minimum of 8 and maximum of 15 characters.
NotEmpty.customer.emailId=Email Id is required. 
Email.customer.emailId=valid email id is required.
NotEmpty.customer.password=Password is required.
Size.customer.password=Password should be minimum of 8 and maximum of 15 characters.

Build the project and copy the war file into webapps folder of Tomcat and start the server.

Access the below url

http://localhost:8080/SpringMVCFormValidationBeanValidator/login

Don’t enter anything, just click on Login button to see the validation

Since we have written @NotEmpty annotation on each field, valdator throws error if the fields are empty.

Enter Invalid Email format as below and see @Email throws validation error

Since we have used resource bundle message source for localization, all Customized error messages are coming from messages.properties file. Otherwise we will see default error messages.

Now enter valid email and password and click on Login

And see the below home page

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on