`

Spring MVC学习(七)-------SpringMVC数据验证

 
阅读更多

7.4、数据验证

7.4.1、编程式数据验证

Spring 2.x提供了编程式验证支持,详见【4.16.2 数据验证】章节,在此我们重写【4.16.2.4.1、编程式验证器】一节示例。

(1、验证器实现

复制cn.javass.chapter4.web.controller.support.validator.UserModelValidator

到cn.javass.chapter7.web.controller.support.validator.UserModelValidator。

(2、控制器实现

Java代码收藏代码
  1. @Controller
  2. publicclassRegisterSimpleFormController{
  3. privateUserModelValidatorvalidator=newUserModelValidator();
  4. @ModelAttribute("user")//①暴露表单引用对象为模型数据
  5. publicUserModelgetUser(){
  6. returnnewUserModel();
  7. }
  8. @RequestMapping(value="/validator",method=RequestMethod.GET)
  9. publicStringshowRegisterForm(){//②表单展示
  10. return"validate/registerAndValidator";
  11. }
  12. @RequestMapping(value="/validator",method=RequestMethod.POST)
  13. publicStringsubmitForm(
  14. @ModelAttribute("user")UserModeluser,
  15. Errorserrors){//③表单提交
  16. validator.validate(user,errors);//1调用UserModelValidator的validate方法进行验证
  17. if(errors.hasErrors()){//2如果有错误再回到表单展示页面
  18. returnshowRegisterForm();
  19. }
  20. return"redirect:/success";
  21. }
  22. }

在submitForm方法中,我们首先调用之前写的UserModelValidator的validate方法进行验证,当然此处可以直接验证并通过Errors接口来保留错误;此处还通过 Errors接口的hasErrors方法来决定当验证失败时显示的错误页面。

(3、spring配置文件chapter7-servlet.xml

Java代码收藏代码
  1. <beanclass="cn.javass.chapter7.web.controller.RegisterSimpleFormController"/>

(4、错误码配置(messages.properties),需要执行NativeToAscii

直接将【springmvc-chapter4】项目中src下的messages.properties复制到src目录下。

在spring配置文件chapter7-servlet.xml中添加messageSource:

Java代码收藏代码
  1. <beanid="messageSource"
  2. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  3. <propertyname="basename"value="classpath:messages"/>
  4. <propertyname="fileEncodings"value="utf-8"/>
  5. <propertyname="cacheSeconds"value="120"/>
  6. </bean>

(5、视图页面(/WEB-INF/jsp/registerAndValidator.jsp)

直接将【springmvc-chapter4】项目中的/WEB-INF/jsp/registerAndValidator.jsp复制到当前项目下的/WEB-INF/jsp/validate/registerAndValidator.jsp。

(6、启动服务器测试:

在浏览器地址栏输入http://localhost:9080/springmvc-chapter7/validator进行测试,测试步骤和【4.16.2.4.1、编程式验证器】一样。

其他编程式验证的使用,请参考【4.16.2 数据验证】章节。

7.4.2、声明式数据验证

Spring3开始支持JSR-303验证框架,JSR-303支持XML风格的和注解风格的验证,接下来我们首先看一下如何和Spring集成。

7.4.2.1、集成

(1、添加jar包:

此处使用Hibernate-validator实现(版本:hibernate-validator-4.3.0.Final-dist.zip),将如下jar包添加到classpath(WEB-INF/lib下即可):

写道
dist/lib/required/validation-api-1.0.0.GA.jar JSR-303规范API包
dist/hibernate-validator-4.3.0.Final.jar Hibernate 参考实现

(2、在Spring配置总添加对JSR-303验证框架的支持

Java代码收藏代码
  1. <!--以下validatorConversionService在使用mvc:annotation-driven会自动注册-->
  2. <beanid="validator"
  3. class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
  4. <propertyname="providerClass"value="org.hibernate.validator.HibernateValidator"/>
  5. <!--如果不加默认到使用classpath下的ValidationMessages.properties-->
  6. <propertyname="validationMessageSource"ref="messageSource"/>
  7. </bean>

此处使用Hibernate validator实现:

validationMessageSource属性:指定国际化错误消息从哪里取,此处使用之前定义的messageSource来获取国际化消息;如果此处不指定该属性,则默认到classpath下的ValidationMessages.properties取国际化错误消息。

通过ConfigurableWebBindingInitializer注册validator:

Java代码收藏代码
  1. <beanid="webBindingInitializer"
  2. class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
  3. <propertyname="conversionService"ref="conversionService"/>
  4. <propertyname="validator"ref="validator"/>
  5. </bean>

其他配置和之前学习7.2.2.4一节一样。

如上集成过程看起来比较麻烦,后边我们会介绍<mvc:annotation-driven>和@EnableWebMvc,ConversionService会自动注册,后续章节再详细介绍。

(3、使用JSR-303验证框架注解为模型对象指定验证信息

Java代码收藏代码
  1. packagecn.javass.chapter7.model;
  2. importjavax.validation.constraints.NotNull;
  3. publicclassUserModel{
  4. @NotNull(message="{username.not.empty}")
  5. privateStringusername;
  6. }

通过@NotNull指定此username字段不允许为空,当验证失败时将从之前指定的messageSource中获取“username.not.empty”对于的错误信息,此处只有通过“{错误消息键值}”格式指定的才能从messageSource获取。

(4、控制器

Java代码收藏代码
  1. packagecn.javass.chapter7.web.controller.validate;
  2. //省略import
  3. @Controller
  4. publicclassHelloWorldController{
  5. @RequestMapping("/validate/hello")
  6. publicStringvalidate(@Valid@ModelAttribute("user")UserModeluser,Errorserrors){
  7. if(errors.hasErrors()){
  8. return"validate/error";
  9. }
  10. return"redirect:/success";
  11. }
  12. }

通过在命令对象上注解@Valid来告诉Spring MVC此命令对象在绑定完毕后需要进行JSR-303验证,如果验证失败会将错误信息添加到errors错误对象中。

(5、验证失败后需要展示的页面(/WEB-INF/jsp/validate/error.jsp)

Java代码收藏代码
  1. <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%>
  2. <%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%>
  3. <form:formcommandName="user">
  4. <form:errorspath="*"cssStyle="color:red"></form:errors><br/>
  5. </form:form>

(6、测试

在浏览器地址栏中输入http://localhost:9080/springmvc-chapter7/validate/hello,即没有username数据,请求后将直接到验证失败界面并显示错误消息“用户名不能为空”,如果请求时带上“?username=zhang”将重定向到成功页面。

到此集成就完成,接下来我们详细学习下有哪些验证约束注解吧。

7.4.2.2、内置的验证约束注解

内置的验证约束注解如下表所示(摘自hibernate validator reference):

验证注解

验证的数据类型

说明

@AssertFalse

Boolean,boolean

验证注解的元素值是false

@AssertTrue

Boolean,boolean

验证注解的元素值是true

@NotNull

任意类型

验证注解的元素值不是null

@Null

任意类型

验证注解的元素值是null

@Min(value=值)

BigDecimal,BigInteger, byte,

short, int, long,等任何Number或CharSequence(存储的是数字)子类型

验证注解的元素值大于等于@Min指定的value值

@Max(value=值)

和@Min要求一样

验证注解的元素值小于等于@Max指定的value值

@DecimalMin(value=值)

和@Min要求一样

验证注解的元素值大于等于@ DecimalMin指定的value值

@DecimalMax(value=值)

和@Min要求一样

验证注解的元素值小于等于@ DecimalMax指定的value值

@Digits(integer=整数位数, fraction=小数位数)

和@Min要求一样

验证注解的元素值的整数位数和小数位数上限

@Size(min=下限, max=上限)

字符串、Collection、Map、数组等

验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小

@Past

java.util.Date,

java.util.Calendar;

Joda Time类库的日期类型

验证注解的元素值(日期类型)比当前时间早

@Future

与@Past要求一样

验证注解的元素值(日期类型)比当前时间晚

@NotBlank

CharSequence子类型

验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首位空格

@Length(min=下限, max=上限)

CharSequence子类型

验证注解的元素值长度在min和max区间内

@NotEmpty

CharSequence子类型、Collection、Map、数组

验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)

@Range(min=最小值, max=最大值)

BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型

验证注解的元素值在最小值和最大值之间

@Email(regexp=正则表达式,

flag=标志的模式)

CharSequence子类型(如String)

验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式

@Pattern(regexp=正则表达式,

flag=标志的模式)

String,任何CharSequence的子类型

验证注解的元素值与指定的正则表达式匹配

@Valid

任何非原子类型

指定递归验证关联的对象;

如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证

此处只列出Hibernate Validator提供的大部分验证约束注解,请参考hibernate validator官方文档了解其他验证约束注解和进行自定义的验证约束注解定义。

具体演示实例请参考cn.javass.chapter7.web.controller.validate.ValidatorAnnotationTestController。

7.4.2.3、错误消息

当验证出错时,我们需要给用户展示错误消息告诉用户出错的原因,因此我们要为验证约束注解指定错误消息。错误消息是通过在验证约束注解的message属性指定。验证约束注解指定错误消息有如下两种方式:

1、硬编码错误消息;

2、从资源消息文件中根据消息键读取错误消息。

一、硬编码错误消息

直接在验证约束注解上指定错误消息,如下所示:

Java代码收藏代码
  1. @NotNull(message="用户名不能为空")
  2. @Length(min=5,max=20,message="用户名长度必须在5-20之间")
  3. @Pattern(regexp="^[a-zA-Z_]\\w{4,19}$",message="用户名必须以字母下划线开头,可由字母数字下划线组成")
  4. privateStringusername;

如上所示,错误消息使用硬编码指定,这种方式是不推荐使用的,因为在如下场景是不适用的:

1、在国际化场景下,需要对不同的国家显示不同的错误消息;

2、需要更换错误消息时是比较麻烦的,需要找到相应的类进行更换,并重新编译发布。

二、从资源消息文件中根据消息键读取错误消息

2.1、默认的错误消息文件及默认错误消息键值

默认的错误消息文件是/org/hibernate/validator/ValidationMessages.properties,如下图所示:



默认的错误消息键值如下图所示:



消息键默认为:验证约束注解的全限定类名.message

在我们之前的测试文件中,错误消息键值是使用默认的,如何自定义错误消息文件和错误消息键值呢?

2.2、自定义的错误消息文件和错误消息键值

自定义的错误消息文件里的错误消息键值将覆盖默认的错误消息文件中的错误消息键值。我们自定义的错误消息文件是具有国际化功能的。

(1、定义错误消息文件

在类装载路径的根下创建ValidationMessages.properties文件,如在src目录下创建会自动复制到类装载路径的根下,并添加如下消息键值(需要native2ascii,可以在eclipse里装PropertiesEditor,自动保存为ASCII码):

Java代码收藏代码
  1. javax.validation.constraints.Pattern.message=用户名必须以字母或下划线开头,后边可以跟字母数字下划线,长度在5-20之间

需要在你的spring配置文件WEB-INF/chapter7-servlet.xml修改之前的validator Bean:

Java代码收藏代码
  1. <beanid="validator"
  2. class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
  3. <propertyname="providerClass"
  4. value="org.hibernate.validator.HibernateValidator"/>
  5. </bean>

此时错误消息键值的查找会先到classpath下ValidationMessages.properties中找,找不到再到默认的错误消息文件中找。

输入测试地址:http://localhost:9080/springmvc-chapter7/validate/pattern?value=zhan,将看到我们自定义的错误消息显示出来了。

(2、使用Spring的MessageSource Bean进行消息键值的查找

如果我们的环境是与spring集成,还是应该使用Spring提供的消息支持,具体配置如下:

在spring配置文件WEB-INF/chapter7-servlet.xml定义MessageSource Bean:

Java代码收藏代码
  1. <beanid="messageSource"
  2. class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  3. <propertyname="basename"value="classpath:messages"/>
  4. <propertyname="fileEncodings"value="utf-8"/>
  5. <propertyname="cacheSeconds"value="120"/>
  6. </bean>

之前我们已经配置过了,在此就不详述了。

在spring配置文件WEB-INF/chapter7-servlet.xml定义的validator Bean,添加如下属性:

Java代码收藏代码
  1. <propertyname="validationMessageSource"ref="messageSource"/>

验证失败的错误消息键值的查找将使用messageSource Bean进行。

在消息文件src/messages.properties中添加如下错误消息:

Java代码收藏代码
  1. javax.validation.constraints.Pattern.message=用户名必须以字母或下划线开头,后边可以跟字母数字下划线,长度在5-20之间

输入测试地址:http://localhost:9080/springmvc-chapter7/validate/pattern?value=zhan,将看到我们自定义的错误消息显示出来了。

当我们配置了messageSource Bean时,默认将为验证的对象自动生成如下错误消息键:

验证错误注解简单类名.验证对象名.字段名

验证错误注解简单类名.字段名

验证错误注解简单类名.字段类型全限定类名

验证错误注解简单类名

使用的优先级是:从高到低,即最前边的具有最高的优先级,而且以上所有默认的错误消息键优先级高于自定义的错误消息键。

如测试用例cn.javass.chapter7.web.controller.validate.ValidatorAnnotationTestController中的public String pattern(@Valid @ModelAttribute("model") PatternModel model, Errors errors)将自动产生如下错误消息键:

Pattern.model.value=验证错误注解简单类名.验证对象名.字段名

Pattern.value=验证错误注解简单类名.字段名

Pattern.java.lang.String=验证错误注解简单类名.字段类型全限定类名

Pattern=验证错误注解简单类名

(3、自定义错误消息键值

之前我们已经学习了硬编码错误消息,及默认的错误消息,在大部分场景下,以上两种方式无法满足我们的需求,因此我们需要自定义错误消息键值。

在验证约束注解上指定错误消息键:

Java代码收藏代码
  1. packagecn.javass.chapter7.web.controller.validate.model;
  2. publicclassPatternModel{
  3. @Pattern(regexp="^[a-zA-Z_][\\w]{4,19}$",message="{user.name.error}")
  4. privateStringvalue;
  5. }

我们可以通过验证约束注解的message属性指定错误消息键,格式如“{消息键}”。

在消息文件src/messages.properties中添加如下错误消息:

Java代码收藏代码
  1. user.name.error=用户名格式不合法

输入测试地址:http://localhost:9080/springmvc-chapter7/validate/pattern?value=zhan,将看到我们自定义的错误消息显示出来了。

接下来我们看下如下场景

Java代码收藏代码
  1. @Length(min=5,max=20,message="{user.name.length.error}")
Java代码收藏代码
  1. user.name.error=用户名长度必须在5-20之间

错误消息中的5-20应该是从@Length验证约束注解中获取的,而不是在错误消息中硬编码,因此我们需要占位符的支持:

●如@Length(min=5, max=20, message="{user.name.length.error}"),错误消息可以这样写:用户名长度必须在{min}-{max}之间

错误消息占位符规则:

{验证注解属性名},如@Length有min和max属性,则在错误消息文件中可以通过{min}和{max}来获取;如@Max有value属性,则在错误消息文件中可以通过{value}来获取。

Java代码收藏代码
  1. user.name.length.error=用户名长度必须在{min}-{max}之间

输入测试地址:http://localhost:9080/springmvc-chapter7/validate/length?value=1,将看到我们自定义的错误消息显示出来了。

7.4.2.4、功能处理方法上多个验证参数的处理

当我们在一个功能处理方法上需要验证多个模型对象时,需要通过如下形式来获取验证结果:

Java代码收藏代码
  1. @RequestMapping("/validate/multi")
  2. publicStringmulti(
  3. @Valid@ModelAttribute("a")Aa,BindingResultaErrors,
  4. @Valid@ModelAttribute("b")Bb,BindingResultbErrors){
  5. if(aErrors.hasErrors()){//如果a模型对象验证失败
  6. return"validate/error";
  7. }
  8. if(bErrors.hasErrors()){//如果a模型对象验证失败
  9. return"validate/error";
  10. }
  11. return"redirect:/success";
  12. }

每一个模型对象后边都需要跟一个Errors或BindingResult对象来保存验证结果,其方法体内部可以使用这两个验证结果对象来选择出错时跳转的页面。详见cn.javass.chapter7.web.controller.validate.MultiModelController。

在错误页面,需要针对不同的模型来显示错误消息:

Java代码收藏代码
  1. <form:formcommandName="a">
  2. <form:errorspath="*"cssStyle="color:red"></form:errors><br/>
  3. </form:form>
  4. <form:formcommandName="b">
  5. <form:errorspath="*"cssStyle="color:red"></form:errors><br/>
  6. </form:form>

分享到:
评论

相关推荐

    由Spring-SpringMVC-MyBatis-MySQL数据库开发的一个博客系统源码.zip

    由Spring-SpringMVC-MyBatis-MySQL数据库开发的一个博客系统 技术 后端 Spring Spring MVC MyBatis druid-数据库连接池 PageHelper-Mybatis通用分页插件 FreeMarker-模板引擎 前端 Bootstrap jQuery jQuery Form Vue...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南.rar

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

    springmvc数据验证

    这个能很简单并快捷的配置完成数据校验,提高安全性,并提高开发效率,以及提高系统的安全性以及高效性

    Spring MVC学习指南 第2版 高清版

    全书共包括13章和5个附录,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、转换器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件以及应用测试等多个角度介绍...

    Spring Mvc(1)Spring MVC 校验

    Spring Mvc(1)Spring MVC 校验 springmvc 基本校验 springmvc 自定义校验 springmvc 组合校验

    springmvc数据验证jar包

    hibernate-validator, jboss-logging validation-api等包

    Spring MVC依赖包

    Spring mvc依赖包 Spring mvc都做了些什么 Controller为中心完成对系统流程的控制管理 从请求中搜集数据 对传入的参数进行验证 将结果返回给视图 针对不同的视图提供不同的解决方案 针对jsp视图技术提供标签库 拦截...

    vip会员登录系统结合spring + mvc +hibernate

    spring+springmvc+hibernate整合框架Demo,在此基础上开发或学习。其中包含apache的log4j记录日志信息,spring管理组件,springmvc分层,springaop配置数据库事务控制,hibernate二级缓存配置,实现了查询,用户登录...

    springmvc demo

    Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC...提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

    firstssm:我的第一个Spring-SpringMVC-Mybatis应用程序

    数据校验jquery初步验证+ JSR303初步验证 阿贾克斯 Rest风格的URI,即使用HTTP协议请求方式的动词,来表示对资源的操作 技术点: 基础框架-ssm(SpringMVC + Spring + MyBatis) 数据库-MySQL 前端框架-bootstrap ...

    spring mvc 登陆验证

    最简单的Spring MVC 架构的登陆验证系统。

    SpringMVC-SpringSecurity-MySql-Hibernate

    配置Spring Security并创建经过身份验证的页面,例如“登录”页面和“管理页面” 。 用于在具有授权角色的数据库上创建安全用户的安全上下文集成。 (本教程使用的是JNDI数据源; &lt;jee:jndi-lookup id=...

    sample-springmvc-portlet:像附加组件一样打包的 Spring MVC Portlet 示例

    本示例中使用了以下功能: Spring MVC Portlet 动作和渲染映射依赖注入(使用@Inject) 表单绑定表单验证(Hibernate Validator)入门第 1 步:安装先决条件:安装(EXO_TOMCAT_ROOT_FOLDER 将用于指定 eXo Tomcat ...

    SpringMVC学习指南.pdf

    全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...

    spring-mvc-showcase:SpringMVC

    Spring MVC 展示 通过小而简单的示例演示 Spring MVC Web 框架的功能。 在查看了这个展示之后,您应该对 Spring MVC 可以做什么有一个很好的理解,并感受到它的易用性。 包括项目代码以及支持幻灯片和屏幕投射。 在...

    SpringMVC数据验证——注册用户格式的验证实例

    SpringMVC数据验证——注册用户格式的验证实例,具体过程和效果看博文http://blog.csdn.net/evankaka/article/details/45789283

    spring mvc服务端表单验证实例

    spring mvc服务端表单验证实例 能跑起来看效果 lib齐全 希望对您的学习有帮助

    spring mvc 3.2 参考文档

    Spring的数据绑定是高度灵活的: 例如,它把类型不匹配当做验证错误,这样就可以算作应用程序错误,而不是系统错误。因此你不需要简单的重复拷贝您的业务对象的属性,表单对象中的非类型化的字符串只是处理无效的...

Global site tag (gtag.js) - Google Analytics