一 简介

SpringMVC支持与JSR 349 Bean Validation API的集成。借助于Bean验证,可以非常容易地将验证元数据应用到实体类,并且通过合适的视图向用户展示可能的错误结果。在模型类中可以通过注解对属性验证进行定义,常见的注解有:@Size ,@Email ,@Pattern,@Max等,分别验证长度,邮箱格式,自定义正则表达式,最大值(PS:更多相关注解可以百度或者查API)


二 测试实例

(1)新建一个动态Java web项目,然后下载“Hibernate Validator”的jar包,下载地址:http://hibernate.org/validator/,最后是导入必要的几个jar包和springmvc所需要的jar包,最后的项目结构如下:

(2)配置文件web.xml:

<web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.html</url-pattern></servlet-mapping><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping></web-app>

在web.xml中定义了springmvc处理请求的后缀是.html,同时设置了编码为UTF-8

(3)配置文件springmvc-servlet.xml:

<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"><context:component-scanbase-package="cn.zifangsky.**.controller"/><context:annotation-config/><!--激活Bean中定义的注解--><mvc:annotation-drivenvalidator="validator"/><!--视图相关配置--><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/pages/"/><!--视图前缀--><propertyname="suffix"value=".jsp"/><!--视图后缀--></bean><beanid="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><propertyname="basename"value="classpath:errors"/></bean><beanid="validator"class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"><propertyname="validationMessageSource"ref="messageSource"/></bean></beans>

在这里,主要是配置了视图相关配置,国际化(PS:在这里就是根据中文和英文网页显示不同的错误提示信息),以及定义了验证相关的配置。需要注意的是,还需要在mvc命名空间的annotation-driven标签中定义验证程序

(4)两个国际化文件errors_zh_CN.properties和errors_en_US.properties:

errors_zh_CN.properties文件:

error.password=\u5BC6\u7801\u662F\u5FC5\u987B\u540C\u65F6\u5305\u542B\u5927\u5199\u5B57\u6BCD\u3001\u5C0F\u5199\u5B57\u6BCD\u548C\u6570\u5B57\u76846-20\u4F4D\u5B57\u7B26error.username=\u7528\u6237\u540d\u9700\u8981\u0033\u002d\u0032\u0030\u4f4derror.age=\u5e74\u9f84\u6700\u5927\u662f\u0031\u0032\u0030\u5c81

这里以键值对的形式定义了三个中文错误提示信息,需要注意的是使用了“Unicode编码”,如果开发工具不能自动编码的话,可以在这个网页进行手动转换编码:http://tool.chinaz.com/tools/unicode.aspx

errors_en_US.properties文件:

error.password=Passwordsare6-20bitcharactersthatmustcontainbothupperandlowercaselettersanddigitsatthesametime.error.username=usernameneeds3-20bitcharacterserror.age=Maxageis120yearsold

(5)实体类User.java:

packagecn.zifangsky.model;importjavax.validation.constraints.Max;importjavax.validation.constraints.Pattern;importjavax.validation.constraints.Size;importorg.hibernate.validator.constraints.Email;publicclassUser{@Size(min=3,max=20,message="{error.username}")privateStringusername;@EmailprivateStringemail;@Pattern(regexp="^((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])).{6,20}$",message="{error.password}")privateStringpassword;@Max(value=120,message="{error.age}")privateintage;publicStringgetUsername(){returnusername;}publicvoidsetUsername(Stringusername){this.username=username;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.email=email;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.password=password;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}}

这里验证了:用户名必须是3-20位,如果验证不通过则通过配置的“message”参数根据语言环境在前台页面显示错误提示信息;邮箱使用默认配置验证了邮箱格式是否正确;密码这一项通过一个正则表达式验证了必须是包含大写字母、小写字母和数字的6-20位的字符;年龄验证了最大是120岁

(6)UserController.java这个controller类:

packagecn.zifangsky.controller;importjavax.validation.Valid;importorg.springframework.stereotype.Controller;importorg.springframework.validation.BindingResult;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.servlet.ModelAndView;importcn.zifangsky.model.User;@ControllerpublicclassUserController{@RequestMapping(value="/form")publicModelAndViewuser(){ModelAndViewmodelAndView=newModelAndView("userForm");modelAndView.addObject("user",newUser());returnmodelAndView;}@RequestMapping(value="/result",method=RequestMethod.POST)publicModelAndViewprocessUser(@ValidUseruser,BindingResultresult){ModelAndViewmodelAndView=newModelAndView("userResult");modelAndView.addObject("u",user);//如果出现验证错误,则转到"userForm"视图if(result.hasErrors()){modelAndView.setViewName("userForm");}else{modelAndView.setViewName("userResult");}returnmodelAndView;}}

从代码可以看出,定义了两个方法,user方法负责处理”/form”请求,然后转到“userForm.jsp”这个视图页面;在processUser方法中,对用户输入的验证由@Valid注解触发,该注解被递归地应用到实体类User的各个属性中。同时在这个方法中接收了一个额外的参数result,该参数是一个BindingResult实例,通过使用该参数来检查在将请求参数映射到实体类属性的过程中是否发生了任何验证错误。最后是根据条件转到相关视图页面

(7)三个前台jsp页面:

i)根目录下的index.jsp:

<%response.sendRedirect("form.html");%>

这个文件就简单的一句话,在项目启动时直接请求“form.html”

ii)userForm.jsp:

<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%@tagliburi="http://www.springframework.org/tags/form"prefix="mvc"%><html><head><title>SpringMVCForm表单验证</title><styletype="text/css">.formFieldError{background-color:#FAFFBD;}</style></head><body><h3>用户注册:</h3><mvc:formmodelAttribute="user"action="result.html"><table><tr><td><mvc:labelpath="username">用户名:</mvc:label></td><td><mvc:inputpath="username"cssErrorClass="formFieldError"/></td><td><mvc:errorspath="username"/></td></tr><tr><td><mvc:labelpath="email">邮箱:</mvc:label></td><td><mvc:inputpath="email"cssErrorClass="formFieldError"/></td><td><mvc:errorspath="email"/></td></tr><tr><td><mvc:labelpath="password">密码:</mvc:label></td><td><mvc:passwordpath="password"cssErrorClass="formFieldError"/></td><td><mvc:errorspath="password"/></td></tr><tr><td><mvc:labelpath="age">年龄:</mvc:label></td><td><mvc:inputpath="age"cssErrorClass="formFieldError"/></td><td><mvc:errorspath="age"/></td></tr><tr><tdcolspan="3"><inputtype="submit"value="Submit"/></td></tr></table></mvc:form></body></html>

这个文件中定义的errors标签就是分别显示各个参数验证之后的错误提示信息

iii)userResult.jsp:

<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%@tagliburi="http://www.springframework.org/tags/form"prefix="mvc"%><html><head><title>SpringMVCForm表单验证结果</title></head><body><h3>用户注册结果</h3><table><tr><td>用户名:</td><td>${u.username}</td></tr><tr><td>邮箱:</td><td>${u.email}</td></tr><tr><td>密码:</td><td>${u.password}</td></tr><tr><td>年龄:</td><td>${u.age}</td></tr></table></body></html>

这个文件只是简单的信息展示,不多做解释

三 测试

(1)中文环境下的错误提示:

项目启动后,使用中文类型的浏览器填写表单,可以发现,出现错误后显示的提示信息如下:

可以发现,出现了预期的提示效果

(2)英文环境下的错误提示:

由于我装的浏览器是中文的,而且也不想更改浏览器的语言,因此我通过在提交表单时抓包手动更改Header中的“Accept-Language”这一项属性,改成“en-US,en;q=0.5”,相当于给服务端说我是英语环境(PS:q参数表示用户的喜爱度,不用管,随便设一个就行)

最后的显示效果如下:

注:实际上,应该把页面中其他的一些中文也设置成国际化形式,那样就可以在英文环境中显示成英文了。不过为了减小理解难度,因此在这里就没有添加上这个步骤,当然我在后面可能会单独写一写SpringMVC的国际化