Spring 3 MVC and JSR303 @Valid example

In Spring 3, you can enable “mvc:annotation-driven” to support JSR303 bean validation via @Valid annotation, if any JSR 303 validator framework on the classpath.

Note
Hibernate Validator is the reference implementation for JSR 303

In this tutorial, we show you how to integrate Hibernate validator with Spring MVC, via @Valid annotation, to perform bean validation in a HTML form.

Technologies used :

  1. Spring 3.0.5.RELEASE
  2. Hibernate Validator 4.2.0.Final
  3. JDK 1.6
  4. Eclipse 3.6
  5. Maven 3

1. Project Dependencies

Hibernate validator is available at JBoss public repository.


	<repositories>
		<repository>
			<id>JBoss repository</id>
			<url>http://repository.jboss.org/nexus/content/groups/public/</url>
		</repository>
	</repositories>
	
	<properties>
		<spring.version>3.0.5.RELEASE</spring.version>
	</properties>

	<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>

		<!-- Hibernate Validator -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.2.0.Final</version>
		</dependency>

	</dependencies>

2. JSR303 Bean Validation

A simple POJO, annotated with Hibernate validator annotation.

Note
Refer to this Hibernate validator documentation for detail explanation

package com.mkyong.common.model;

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

public class Customer {

	@NotEmpty //make sure name is not empty
	String name;

	@Range(min = 1, max = 150) //age need between 1 and 150
	int age;

	//getter and setter methods

}

3. Controller + @Valid

For validation to work, just annotate the “JSR annotated model object” via @Valid. That’s all, other stuff is just a normal Spring MVC form handling.


package com.mkyong.common.controller;

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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.mkyong.common.model.Customer;

@Controller
@RequestMapping("/customer")
public class SignUpController {

	@RequestMapping(value = "/signup", method = RequestMethod.POST)
	public String addCustomer(@Valid Customer customer, BindingResult result) {

		if (result.hasErrors()) {
			return "SignUpForm";
		} else {
			return "Done";
		}

	}

	@RequestMapping(method = RequestMethod.GET)
	public String displayCustomerForm(ModelMap model) {

		model.addAttribute("customer", new Customer());
		return "SignUpForm";

	}

}

4. Error Message

By default, if validation failed.

  1. @NotEmpty will display “may not be empty”
  2. @Range will display “must be between 1 and 150”

You can override it easily, create a properties with “key” and message. To know which @annotation bind to which key, just debug it and view value inside “BindingResult result“. Normally, the key is “@Annotation Name.object.fieldname“.

File : messages.properties


NotEmpty.customer.name = Name is required!
Range.customer.age = Age value must be between 1 and 150

5. mvc:annotation-driven

Enable “mvc:annotation-driven” to make Spring MVC supports JSR303 validator via @Valid, and also bind your properties file.


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

	<context:component-scan base-package="com.mkyong.common.controller" />

         <!-- support JSR303 annotation if JSR 303 validation present on classpath -->
	<mvc:annotation-driven />

	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>
    
        <!-- bind your messages.properties -->
	<bean class="org.springframework.context.support.ResourceBundleMessageSource"
		id="messageSource">
		<property name="basename" value="messages" />
	</bean>

</beans>

6. JSP Pages

Last one, normal JSP page with Spring form tag library.

File : SignUpForm.jsp


<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}

.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>

<body>
	<h2>Customer SignUp Form - JSR303 @Valid example</h2>

	<form:form method="POST" commandName="customer" action="customer/signup">
		<form:errors path="*" cssClass="errorblock" element="div" />
		<table>
			<tr>
				<td>Customer Name :</td>
				<td><form:input path="name" /></td>
				<td><form:errors path="name" cssClass="error" /></td>
			</tr>
			<tr>
				<td>Customer Age :</td>
				<td><form:input path="age" /></td>
				<td><form:errors path="age" cssClass="error" /></td>
			</tr>
			<tr>
				<td colspan="3"><input type="submit" /></td>
			</tr>
		</table>
	</form:form>

</body>
</html>

File : Done.jsp


<html>
<body>
	<h2>Done</h2>
</body>
</html>

6. Demo

URL : http://localhost:8080/SpringMVC/customer – Customer form page, with 2 text boxes for name and age.

Spring MVC JSR303 demo page

URL : http://localhost:8080/SpringMVC/customer/signup – If you didn’t fill in the form and click on the “submit” button, your customized validation error messages will be displayed.

Spring MVC JSR303 demo page - error message

Download Source Code

References

  1. Spring JSR303 validation documentation
  2. JSR303 bean validation
  3. Hibernate Validator

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
Krish
Guest
Krish

message can be configured to read from the property file, but how to have the values (Min, Max, Range, Pattern, etc.) in the property files?
I don’t want the sizes to be hardcoded in the java class

firstpostcommenter
Guest
firstpostcommenter

can @Valid and @Requestmapping annotations be used together?

DEEPAK MATHUR
Guest
DEEPAK MATHUR

how can i use validation in your customer signup.jsp without hibernate validation and message.properties file in spring3???

trackback
Spring MVC Tutorial

[…] Spring 3 MVC and JSR303 @Valid example Using Hibernate validator (JSR303 implementation) to validate bean in Spring MVC. […]

trackback
Spring 3 MVC hello world example

[…] Spring 3 MVC and JSR303 @Valid example […]

yang
Guest
yang

I made this project. link : http://blog.naver.com/vest2004/220332230651

Sourabh
Guest
Sourabh

I am facing an issue while implementing the same with ajax call..can anybody help me?
http://stackoverflow.com/questions/28656093/spring-4-0-form-validation-issue-using-ajax/28656201?noredirect=1#

this is the link of the question.

Manoj Sawant
Guest
Manoj Sawant
Hi mkYong, I have one question , In Validation Examples you creating references of Customer Model class in. -1) controllers POST() @Valid Customer customer, here reference is customer. -2) in controllers GET() ,model.addAttribute(“customer”, new Customer()); here key is customer. -3) in messages.property file in another example you created NotEmpty.customer.age = age is required, here also we found customer. -4) In SignUpForm.jsp you mentioned commandName=”customer”, I am confusing about that command name “customer”. i am not getting to whom that command name pointing? And most important question is : Will i have to match all the references of Customer with the… Read more »
ravi mca
Guest
ravi mca

this code is not working it gives 404 status code after clicking the submit button in customer page.

please help me any one how to resolve this problem.

Jose
Guest
Jose

I tried to follow your example but can’t get to work with SpringFramework 4.0.2 in JBoss 7.1.1.Final.
BindingResult always returns false.
Could you please, help?

Abbas Zoher Attarwala
Guest
Abbas Zoher Attarwala

Is there a way the validation for one parameter could be dependent on the validation of another parameter?

Arjun Mukherjee
Guest
Arjun Mukherjee

Hi MK,

Thanks for the above example.

My application uses only @RequestParam instead of a command class.

Suppose the above example the request is like below :

@RequestMapping(value = “/signup”, method = RequestMethod.POST)

public ModelAndView addCustomer(@RequestParam(“name”) String custName,@RequestParam(“age”) String custAge,BindingResult result){

….
}

How would you validate the requestparams and display the errors in the input page.
Note : Inorder to get the Input page (/someinoutaction.do) is expensive and calls Web Services.

Arjun Mukherjee
Guest
Arjun Mukherjee

Hi MK,

Thanks for the above example.

My application uses only @RequestParam instead of a command class.

Suppose the above example the request is like below :

@RequestMapping(value = “/signup”, method = RequestMethod.POST)

public ModelAndView addCustomer(@RequestParam(“name”) String custName,@RequestParam(“age”) String custAge,BindingResult result){

….

}

How would you validate the requestparams and display the errors in the input page.

Note : Inorder to get the Input page (/someinoutaction.do) is expensive and calls Web Services.

Philip
Guest
Philip

Just a quick thank you for your great tutorials. You help many people with them I’m sure :-)

trackback
Spring Form Validation,showing error in overlay | BlogoSfera

[…] Suppose I have a some abc.Jsp page Under that I have created AddButton,Which opens the overlay for filling data into Form, On Clicking the Submit Button the data goes to controller where Data getting Validate,if any validation error occur it render back to the page and shows error, Its Working fine but the Actual problem is when page is renderd,the overlay get hide,How do i keep overlay open After Submitting data and showing error on Overlay. I did In this Way http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/ […]

venkatram
Guest
venkatram
Thanks alot! I was actually looking for replacing message string in jpa entity with property file value. I have Tried with injecting apache commonconfig bean to entity through aop. But they gave me errors like we cannot inject any new class as property in entity if it is not a column in the associated table.Then I tried with static resource bundle, getting value from the bundle. But, the message attribute needed constant expression. Finally I have seen your example. How do you know that we can override the default message? What would you made to think like that? Please guide… Read more »
avatar42
Guest
avatar42

After wasting hours trying to find an example of how to make the error messages for @Valid friendly / custom I thought I should add it here. The trick is to but your key in {} as in @NotEmpty(message = “{err.msg}”) Otherwise it returns the key instead of the text for the translated key.

avatar42
Guest
avatar42

pre tag lost in reply. Trying escaped.
Note for the custom error message keys to work, if you do not have already, you will need to add:
<bean id=”messageSource”
class=”org.springframework.context.support.ReloadableResourceBundleMessageSource”>
<property name=”basename”
value=”WEB-INF/classes/messages” />
<property name=”defaultEncoding” value=”UTF-8″ />
</bean>
<bean id=”validator” class=”org.springframework.validation.beanvalidation.LocalValidatorFactoryBean”>
<property name=”validationMessageSource” ref=”messageSource” />
</bean>
<mvc:annotation-driven validator=”validator” />

To your servlet.xml

DEEPAK MATHUR
Guest
DEEPAK MATHUR

hi avatar,
how can i use validation in your customer signup.jsp without hibernate validation and message.properties file in spring3??? can u solve such type of requirement???

Binh Thanh Nguyen
Guest
Binh Thanh Nguyen

Thanks, nice post.

Tarun
Guest
Tarun

Using @Valid results in a HTTP 400 response for me

smith
Guest
smith

Hi,
I am getting this error when i am deploying my application.

WARNING: No mapping found for HTTP request with URI [/] in DispatcherServlet with name ‘mvc-dispatcher’.

kerchunk
Guest
kerchunk

I’m pretty sure this setup will barf if someone were to enter a non-integer into the “age” form field , like the letter “A”, and tried to submit.

gill
Guest
gill

Can we implement jsr 303 validation with ajax instead of form submit in spring

thanks
gill

Quach Thien
Guest
Quach Thien

Hi, your tutorial is very helpful, but I wanna ask you what should I do if I have a insert book page, which has a dropdownlist controller bound data from database. In controller, when (result.hasError()) return ‘true’, if i return ‘book’, the error message display very well, but the data of dropdownlist has been lost. Can you help me?

Ankur Raiyani
Guest
Ankur Raiyani

Hi,

Thanks for sharing helpful tutorial.

I have a bean which contains two fields password and confirm password.
I compare these fields and add below code if they are different.

result.rejectValue("password", "exception.registration.password.mismatch","Password Mismatch");

However, this message doesn’t display on JSP in fact it isn’t added to errors.

Can you please guide as soon as possible?

Thanks

Ankur
Guest
Ankur

Problem Resolved !! :)

Juzer Ali
Guest
Juzer Ali

Its not mentioned that this example would require a validations-api jar as well. After looking at the Pom.xml I thought this is all what is needed and spent a couple of hours trying to figure out why my project is showing error.

Ramath
Guest
Ramath

Is there a option to this Hibernate validation or any annotated validation framework in standalone Java application using Spring 3.0 framework . Thanks.

Sunil
Guest
Sunil

I have down loaded same project and imported into eclipse.
But I’m not getting any errors for bad inputs also. Can any body help me on this.

The following code always returning false.

 if (result.hasErrors()) 

Thanks
Sunil

Sunil
Guest
Sunil

sorry! ,

After coping hibernate jar into server lib , working fine.

Anyway Thanks MkYoung :-)

David Cook
Guest
David Cook

I have the validation working to the point it validates and generates error, but I can’t get it back to my jsp page. If I just return a reference to the page it gives me a 404. If I return a redirect to the page it goes to the page but with no errors. This is in applying your tutorial to my own project.

The start of the function in my controller is as follows

@RequestMapping(value = "/createProject", method = RequestMethod.POST)
	public String createProject(HttpServletRequest request, HttpServletResponse response, @Valid Project project, BindingResult result)
	{
		if(result.hasErrors())
		{
			//request.setAttribute("errors", errors);
			return "project/creatProject";
		}
David Cook
Guest
David Cook

Of note I am using an internalResourceViewResolver in my xml. Can it be done with that view resolver?

David Cook
Guest
David Cook

Never mind got it sorted out. Typo in createProject.

this url
Guest
this url

Wonderful work! That is the kind of information that are supposed to be shared across the net.
Disgrace on the seek engines for no longer positioning this submit higher!
Come on over and discuss with my site . Thanks =)

trackback
article-stack » Spring 3 MVC Form Handling – covering all aspects – Theory apart – Part 2

[…] If you google “spring 3 mvc form validation”, you’ll surely get many good tutorials. So why to increase data redundancy over internet. Here I am just explaining setup require for validation and summary of required annotations. You’ll have to go through my first article quick jump with spring 3 MVC for project setup. You can also refer a good tutorial at mkyong […]