项目中使用较多的是前端的校验,比如页面中js校验。对于安全要求较高的建议在服务端进行校验。
服务端校验:
控制层controller:校验页面请求的参数的合法性,在服务端控制层controller校验,不区分客户端类型(浏览器、手机客户端、远程调用)
业务层service:主要校验关键业务参数,仅限于service接口中使用的参数
持久层dao:一般是不校验的。
springmvc校验
springmvc使用hibernate的校验框架validation(和hibernate没有任何关系)
校验思路:
页面提交请求的参数,请求controller方法中,使用validation进行校验。
如果校验出错,将错误信息展示到页面。
validation所需依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate.validator.version}</version>
</dependency>
配置校验器
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!--校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!--资源文件名-->
<property name="basenames">
<list>
<!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找 -->
<value>classpath:messages</value>
</list>
</property>
<property name="useCodeAsDefaultMessage" value="false" />
<!--资源文件编码格式-->
<property name="defaultEncoding" value="UTF-8" />
<!--对资源文件内容缓存时间,单位秒-->
<property name="cacheSeconds" value="60" />
</bean>
添加校验器到处理器适配器中
<mvc:annotation-driven conversion-service="conversionService"
validator="validator"></mvc:annotation-driven>
在pojo中添加校验规则
@Size(min = 1,max=30,message="{item.error}")
private Integer id;
@NotNull(message = "{item.isNull}")
private String reviewId;
//messages配置校验错误信息
item.error=请输入1到30个字符
item.isNull=不能为空
校验方法
在controller中实现
//在需要校验的pojo前加@Validated,在需要校验的pojo后面添加BindingResult bindingResult结束校验出错信息
//@Validated和BindingResult bindingResult是配对出现,并且顺序固定一前一后
@RequestMapping("/queryItems")
public String queryitems(Model model, @Validated ItemsCustom itemsCustom,
BindingResult bindingResult)throws Exception{
//获取校验信息
if(bindingResult.hasErrors()){
//输出错误信息
List<ObjectError> allErrors = bindingResult.getAllErrors();
for (ObjectError objectError :
allErrors) {
System.out.println(objectError.getDefaultMessage());
}
//将错误信息传到页面
model.addAttribute("allErrors",allErrors);
//出错重新到商品修改页面
return "items/editItems";
}
//....一系列操作
}
这种方法有一个问题,在pojo中定义校验规则,而pojo是被多个controller所共用,当不同的controller方法对同一个pojo进行校验,但是每个controller方法需要不同的校验。
这时候就需要用到
分组校验
第一步:创建校验分组
public interface ValidGroup1{
//接口中不需要定义任何方法,仅是对不同的校验规则进行分组
//此分组只校验商品名称长度
}
第二步:添加分组
//group:此校验属于哪个分组,可添加多个
@Size(min = 1,max=30,message="{item.error}",groups = {ValidGroup1.class})
第三步:在controller中指定分组
//value = {ValidGroup1.class}指定使用ValidGroup1分组的校验
@RequestMapping("/queryItems")
public String queryitems(Model model, @Validated(value = {ValidGroup1.class})ItemsCustom itemsCustom, BindingResult bindingResult)throws Exception{