Here's our completely standard web.xml:
/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>contact</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>contact</servlet-name>
<url-pattern>/contact/*</url-pattern>
</servlet-mapping>
</web-app>
Though I said I'm assuming you already know Spring WebMVC, I'll just point out that since I didn't specify a custom location for the application context file, I have to put it at /WEB-INF/contact-servlet.xml. If you want the file to live elsewhere, or if you want it to be associated with the servlet context instead of the DispatcherServlet, you'll have to set that up in web.xml accordingly.
Here's the Spring application context:
/WEB-INF/contact-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- Enable annotation-based validation using Bean Validation Framework -->
<!-- Using these instead of vld namespace to prevent Eclipse from complaining -->
<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"/>
<!-- Load messages -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basenames="errors"/>
<!-- Discover POJO @Components -->
<!-- These automatically register an AutowiredAnnotationBeanPostProcessor -->
<context:component-scan base-package="contact"/>
<!-- Map logical view names to physical views -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/"
p:suffix=".jsp"/>
</beans>
(IMPORTANT: In the configurationLoader definition, make sure you put the class name on a single line. I had to break it up for formatting purposes.)
If you're not familiar with it, I'm using the p namespace here for syntactic sugar—it allows me to specify properties using a nice shorthand.
The first two beans basically create the BeanValidator instance we're going to use. It turns out that instead of defining these two beans explicitly, you can use a special element from a special namespace:
xmlns:vld="http://www.springmodules.org/validation/bean/validator";http://www.springmodules.org/validation/bean/validator-2.0.xsd;<vld:annotation-based-validator id="validator"/>But when I do it, Eclipse complains (even though the code works when you run it) since there isn't at the time of this writing actually an XSD at the specified location. (At least there's a JIRA ticket for it.) So I'll just use the two beans for now.
The other stuff is mostly normal Spring WebMVC stuff. I put the message source on the app context, scan for the controller (which is why I'm autowiring the validator into the controller), and put a view resolver on the context too.
Build and deploy your WAR, and then point your browser to your web app; for example:
http://localhost:8080/contact-example/contact/form
Try submitting the form with empty fields, or an invalid e-mail address, or fields that are too long. If things are working correctly, you ought to see error messages and even field highlighting when validation fails.
And that, my friends, is it! Feel free to post a comment if you run into problems getting it to work and I'll try to help if I can.
Again, if you want to download the sample code (minus dependencies; see above), here it is:
Have fun!