校验器与转换器先后执行问题: 校验器先于转换器执行
1.校验:
1.控制层Controller: 请求参数校验,不区分客户端请求来源(手机客户端,浏览器,远程调用)
2.服务层Servcie(重要:使用较多): 主要校验关键的业务参数,仅限于servvice接口中使用的参数。
3.持久层Dao: 一般不需要校验
2.springMVC校验:
使用了Hibernate的校验框架Validate(和Hibernate框架并没有任何联系)
需要三个jar包
hibernate-validator-xxx.final.jar
jboss-logging.jar
validation-api.jar
3.配置校验器
在springMVC配置文件内配置校验器
4.由于执行Handler(Controller)是由处理器适配器,所以我们需要将校验器注入到处理器适配器
这种配制方法只需要在该标签内添加validator属性,并设定指定的validator即可 (推荐使用)
//如果是使用了独立的HandleAdapter配置方法,则我们需要如下配置
5.因为前端参数和系统pojo直接进行参数绑定,所以我们在pojo中添加校验规则
//校验名称在1-20字符之间
//message表示校验错误信息,和配置文件结合,动态返回错误信息
@Size(min=1,max=20,message="{user.uName.length.error}")
private String uName;
//非空校验
@NotNull(message="{user.address.notNull}")
private String address;
Bean Validation 中内置的 constraint
@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=) 被注释的元素必须在合适的范围内
注解 运行时检查
@AssertFalse 被注解的元素必须为false
@AssertTrue 被注解的元素必须为true
@DecimalMax(value) 被注解的元素必须为一个数字,其值必须小于等于指定的最小值
@DecimalMin(Value) 被注解的元素必须为一个数字,其值必须大于等于指定的最小值
@Digits(integer=, fraction=) 被注解的元素必须为一个数字,其值必须在可接受的范围内
@Future 被注解的元素必须是日期,检查给定的日期是否比现在晚
@Max(value) 被注解的元素必须为一个数字,其值必须小于等于指定的最大值(百度上好多传阅复制写错了 最小值)
@Min(value) 被注解的元素必须为一个数字,其值必须大于等于指定的最小值
@NotNull 被注解的元素必须不为null
@Null 被注解的元素必须为null
@Past(java.util.Date/Calendar) 被注解的元素必须过去的日期,检查标注对象中的值表示的日期比当前早
@Pattern(regex=, flag=) 被注解的元素必须符合正则表达式,检查该字符串是否能够在match指定的情况下被regex定义的正则表达式匹配
@Size(min=, max=) 被注解的元素必须在制定的范围(数据类型:String, Collection, Map and arrays)
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组, 那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验
@CreditCardNumber 对信用卡号进行一个大致的验证
@Email 被注释的元素必须是电子邮箱地址
@Length(min=, max=) 被注解的对象必须是字符串的大小必须在制定的范围内
@NotBlank 被注解的对象必须为字符串,不能为空,检查时会将空格忽略
@NotEmpty 被注释的对象必须为空(数据:String,Collection,Map,arrays)
@Range(min=, max=) 被注释的元素必须在合适的范围内 (数据:BigDecimal, BigInteger, String, byte, short, int, long and 原始类型的包装类 )
@URL(protocol=, host=, port=, regexp=, flags=) 被注解的对象必须是字符串,检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件
6.编写校验错误信息文件
ValidatorMassage.properties
#配置校验出错返回信息
user.uName.length.error="用户名称在1-20个字符之间"
user.address.notNull="用户地址不能够为空"
7.在Controller里面使用校验,抓取校验错误信息
//在需要校验的pojo参数前面加@Validated,在需要校验的pojo参数后面添加BindingResult bindingResult接收校验出错信息
//注意@Validated与BindingResult bindingResult顺序不能发生改变否则出错
@RequestMapping(value="/saveAndSubmit")
public String saveAndSubmit(@Validated User user,BindingResult bindingResult) {
8.将验证错误信息输出到前端
//获取校验出错信息
if(bindingResult.hasErrors()) {
//输出校验出错信息
List<FieldError> fieldErrors= bindingResult.getFieldErrors();//bindingResult.getAllErrors();
// 将错误信息放在此次请求作用域中(仅此次请求有效)
request.setAttribute(err.getField()+"Error",err.getDefaultMessage());
}
9.问题:
如果存在这样的情况,不同的页面对于同一pojo存在不同的校验规则咋办?
解决方案:校验分组
1.定义校验分组接口
package com.ncs.controller.validateGroups;
public interface validatorGroupOne {
//该接口不需要定义任何方法,只是用来对校验进行分组
}
2.为校验规则划分组
//校验名称在1-20字符之间
//message表示校验错误信息,和配置文件结合,动态返回错误信息
//groups表示为校验规则划分组
@Size(min=1,max=20,message="{user.uName.length.error}",groups= {validatorGroupOne.class})
private String uName;
3.使用某一组校验
//在@Validated中添加参数value= {validatorGroupOne.class} 表示选择校验的组别
@RequestMapping(value="/saveAndSubmit")
public String saveAndSubmit(Model Model, @Validated(value= {validatorGroupOne.class}) User user,BindingResult bindingResult) {