SpringMVC学习--校验
- 简介
项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高点建议在服务端进行校验。
服务端校验:
控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
持久层dao:一般是不校验的。
- springmvc校验
springmvc使用hibernate的校验框架validation。
校验思路:页面提交请求的参数,请求到controller方法中,使用validation进行校验。如果校验出错,将错误信息展示到页面。
- 环境准备
hibernate的校验框架validation所需要jar包:
- 配置校验器
1 <!-- 校验器 --> 2 <bean id="validator" 3 class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 4 <!-- hibernate校验器--> 5 <property name="providerClass" value="org.hibernate.validator.HibernateValidator" /> 6 <!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties --> 7 <property name="validationMessageSource" ref="messageSource" /> 8 </bean> 9 <!-- 校验错误信息配置文件 --> 10 <bean id="messageSource" 11 class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 12 <!-- 资源文件名--> 13 <property name="basenames"> 14 <list> 15 <value>classpath:CustomValidationMessages</value> 16 </list> 17 </property> 18 <!-- 资源文件编码格式 --> 19 <property name="fileEncodings" value="utf-8" /> 20 <!-- 对资源文件内容缓存时间,单位秒 --> 21 <property name="cacheSeconds" value="120" /> 22 </bean>
- 校验器注入到处理器适配器中
1 <mvc:annotation-driven conversion-service="conversionService" 2 validator="validator"></mvc:annotation-driven>
- 在POJO中添加校验规则
1 //字符长度在1-30个字符之间 2 //message提示校验出错显示的信息 3 @Size(min=1,max=30,message="{items.length.error.message}") 4 private String name; 5 //创建日期非空校验 6 @NotNull(message="{items.createtime.isNull}") 7 private Date createtime;
- 校验信息配置文件
CustomValidationMessages.properties
- 捕获校验错误和页面显示校验错误信息
1 // 商品信息修改提交 2 @RequestMapping("/editItemsSubmit") 3 public String editItemsSubmit(HttpServletRequest request, Integer id, 4 @Validated ItemsCustom itemsCustom,BindingResult bindingResult) throws Exception { 5 //获取校验错误信息 6 if(bindingResult.hasErrors()){ 7 //输出错误信息 8 List<ObjectError> allerrors = bindingResult.getAllErrors(); 9 for (ObjectError objectError : allerrors) { 10 System.out.println(objectError.getDefaultMessage()); 11 } 12 //将错误信息回显到页面 13 request.setAttribute("allerrors", allerrors); 14 return "items/editItems"; 15 } 16 // 调用service更新商品信息,页面需要将商品信息传到此方法 17 itemsService.updateItems(id, itemsCustom); 18 19 // 重定向到商品查询列表 20 // return "redirect:queryItems.action"; 21 // 页面转发 22 return "forward:queryItems.action"; 23 // return "success"; 24 }
页面显示错误信息:
1 <!-- 显示错误信息 --> 2 <c:if test="${allErrors!=null }"> 3 <c:forEach items="${allErrors }" var="error"> 4 ${ error.defaultMessage}<br/> 5 </c:forEach> 6 </c:if>
- 校验分组
在pojo中定义校验规则,而pojo是被多个 controller所共用,当不同的controller方法对同一个pojo进行校验,但是每个controller方法需要不同的校验。
解决方法:定义多个校验分组(其实是一个java接口),分组中定义有哪些规则,每个controller方法使用不同的校验分组。
1、校验分组
public interface ValidGroup1 { //接口中不需要定义任何方法,仅是对不同的校验规则进行分组 //此分组只校验商品名称长度 }
2、在校验中添加分组信息
1 @Size(min=1,max=30,message="{items.length.error.message}",groups={ValidGroup1.class}) 2 private String name;
3、在controller方法使用指定分组的校验
1 public String editItemsSubmit(HttpServletRequest request, Integer id, 2 @Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult) throws Exception
主要添加如下信息:@Validated(value={ValidGroup1.class})
注解的主要用法:
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内