springmvc使用JSR-303进行数据校验实例
项目中,通常使用较多的是前端的校验,比如页面中js校验以及form表单使用bootstrap校验。然而对于安全要求较高点建议在服务端进行校验。
服务端校验:
- 控制层controller:校验页面请求的参数的合法性。在服务端控制层controller校验,不区分客户端类型。
- 业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
- 持久层dao:一般是不校验的。
环境集成
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.jarJSR-303规范API包
- dist/hibernate-validator-4.3.0.Final.jarHibernate参考实现
2、在spring配置总添加对JSR-303验证框架的支持
<!--校验错误信息配置文件--> <beanid="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <!--资源文件名--> <propertyname="basenames"> <list> <value>classpath:CustomValidationMessages</value> </list> </property> <!--资源文件编码格式--> <propertyname="fileEncodings"value="utf-8"/> <!--对资源文件内容缓存时间,单位秒--> <propertyname="cacheSeconds"value="120"/> </bean>
<!--校验器--> <beanid="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!--hibernate校验器--> <propertyname="providerClass"value="org.hibernate.validator.HibernateValidator"/> <!--指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties--> <propertyname="validationMessageSource"ref="messageSource"/> </bean>
自动注册validator
<mvc:annotation-drivenconversion-service="conversionService"validator="validator"> </mvc:annotation-driven>
例子说明
例子一:
importjavax.validation.constraints.NotNull; publicclassUserModel{ @NotNull(message="{username.not.empty}") privateStringusername; }
通过@NotNull指定此username字段不允许为空,当验证失败时将从之前指定的messageSource中获取“username.not.empty”对于的错误信息,此处只有通过“{错误消息键值}”格式指定的才能从messageSource获取。
@Controller publicclassHelloWorldController{ @RequestMapping("/validate/hello") publicStringvalidate(@Valid@ModelAttribute("user")UserModeluser,Errorserrors){ if(errors.hasErrors()){ return"validate/error"; } return"redirect:/success"; } }
通过在命令对象上注解@Valid来告诉SpringMVC此命令对象在绑定完毕后需要进行JSR-303验证,如果验证失败会将错误信息添加到errors错误对象中。
验证失败后需要展示的页面(/WEB-INF/jsp/error.jsp)
<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%> <%@taglibprefix="form"uri="http://www.springframework.org/tags/form"%> <form:formcommandName="user"> <form:errorspath="*"cssStyle="color:red"></form:errors><br/> </form:form>
在浏览器地址栏中输入http://localhost:8080/validate/hello,即没有username数据,请求后将直接到验证失败界面并显示错误消息“用户名不能为空”,如果请求时带上“?username=zhang”将重定向到成功页面。
例子二:
publicclassItems{ privateIntegerid; @Size(min=1,max=20,message="{items.name.length.error}") privateStringname; @NotNull(message="{items.createtime.isNULL}") privateDatecreatetime; 省略set()和get()... }
publicStringeditItemsSubmit(Modelmodel,@ValidatedItemsitems, BindingResultbindingResult)throwsException{ if(bindingResult.hasErrors()){ List<ObjectError>allErrors=bindingResult.getAllErrors(); for(ObjectErrorobjectError:allErrors){ System.out.println(objectError.getDefaultMessage()); } //可以直接使用model将提交pojo回显到页面 model.addAttribute("items",items); //出错重新到商品修改页面 return"items/editItems"; } return"success"; }
<tablewidth="100%"border=1> <tr> <td>商品名称</td> <td><form:inputtype="text"path="items.name"value="${items.name}"/></td><form:errorspath="items.name"/> </tr> <tr> <td>商品生产日期</td> <td><inputtype="text"name="createtime"value="<fmt:formatDatevalue="${items.createtime}"pattern="yyyy-MM-ddHH:mm:ss"/>"/></td> </tr>
然后jsp页面还是之前的页面,并能显示输入不合法的并通过<form:errorspath="items.name"/>显示出来,这样明显更加简单。
当我们配置了messageSourceBean时,默认将为验证的对象自动生成如下错误消息键:
- 验证错误注解简单类名.验证对象名.字段名
- 验证错误注解简单类名.字段名
- 验证错误注解简单类名.字段类型全限定类名
- 验证错误注解简单类名
使用的优先级是:从高到低,即最前边的具有最高的优先级,而且以上所有默认的错误消息键优先级高于自定义的错误消息键。
如测试用例
publicStringpattern(@Valid@ModelAttribute(“model”)PatternModelmodel,Errorserrors)
将自动产生如下错误消息键:
- Pattern.model.value=验证错误注解简单类名.验证对象名.字段名
- Pattern.value=验证错误注解简单类名.字段名
- Pattern.Java.lang.String=验证错误注解简单类名.字段类型全限定类名
- Pattern=验证错误注解简单类名
内置的验证约束注解如下表所示(摘自hibernatevalidatorreference):
此处只列出HibernateValidator提供的大部分验证约束注解,请参考hibernatevalidator官方文档了解其他验证约束注解和进行自定义的验证约束注解定义。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。