项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高点建议在服务端进行校验。
服务端校验:
控制层conroller:校验页面请求的参数的合法性。在服务端控制层conroller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数。
持久层dao:一般是不校验的。
springmvc校验需求
springmvc使用hibernate的校验框架validation(和hibernate没有任何关系)。
校验思路:
页面提交请求的参数,请求到controller方法中,使用validation进行校验。如果校验出错,将错误信息展示到页面。
具体需求:
商品修改,添加校验(校验商品名称长度,生产日期的非空校验),如果校验出错,在商品修改页面显示错误信息。
配置校验器
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" validator="validator"></mvc:annotation-driven>
在pojo中添加校验规则
1 private Integer id; 2 //校验名称在1-30个字符中间 3 //message:提示的错误信息 4 //标识此校验属于那个分组 5 @Size(min=1,max=30,message="{items.name.length.error}",groups={ValidGroup1.class}) 6 private String name; 7 8 private Float price; 9 10 private String pic; 11 12 //非空校验 13 @NotNull(message="{items.createtime.isNull}") 14 private Date createtime; 15 16 private String detail;
CustomValidationMessages.properties
在CustomValidationMessages.properties配置校验错误信息:
1 #添加校验错误提交信息 2 items.name.length.error=请输入1-30个字符的商品名称 3 items.createtime.isNull=生产日期不能为空
捕获校验错误信息
1 // 在需要校验的pojo前边添加@Validated,在需要校验的pojo后边添加BindingResult 2 // bindingResult接收校验出错信息 3 // 注意:@Validated和BindingResult bindingResult是配对出现,并且形参顺序是固定的(一前一后)。 4 // value={ValidGroup1.class}指定使用ValidGroup1分组的 校验 5 // @ModelAttribute可以指定pojo回显到页面在request中的key 6 @RequestMapping("/editItemsSubmit") 7 public String editItemsSubmit(Model model,HttpServletRequest request,Integer id,@Validated(value={ValidGroup1.class}) ItemsCustom itemsCustom,BindingResult bindingResult) throws Exception { 8 9 //获取错误信息 10 if(bindingResult.hasErrors()){ 11 //输出错误信息 12 List<ObjectError> allErrors = bindingResult.getAllErrors(); 13 for (ObjectError objectError : allErrors) { 14 System.out.println(objectError.getDefaultMessage()); 15 } 16 model.addAttribute("allErrors", allErrors); 17 return "items/editItems"; 18 }
页面显示错误信息:
1 <c:if test="${allErrors!=null }"> 2 <c:forEach items="${allErrors }" var="error"> 3 ${error.defaultMessage } 4 </c:forEach> 5 </c:if>
校验分组
1 public interface ValidGroup1 { 2 //不需要定义任何的方法,仅对不同的校验规则进行分组 3 //此分组只校验商品名称的长度 4 }