在日常开发中,Hibernate Validator经常用来验证bean的字段,基于注解,方便快捷高效。
1、Bean Validation 中内置的 constraint
@Valid 被注释的元素是一个对象,需要检查此对象的所有字段值
@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(value) 被注释的元素必须符合指定的正则表达式
2、Hibernate Validator 附加的 constraint
@Email 被注释的元素必须是电子邮箱地址
@Length(min=, max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=, max=) 被注释的元素必须在合适的范围内
@NotBlank 被注释的字符串的必须非空
@URL(protocol=,host=, port=, regexp=, flags=) 被注释的字符串必须是一个有效的url
@CreditCardNumber 被注释的字符串必须通过Luhn校验算法,银行卡,信用卡等号码一般都用Luhn计算合法性
@ScriptAssert(lang=, script=, alias=) 要有Java Scripting API 即JSR 223 ("Scripting for the JavaTM Platform")的实现
@SafeHtml(whitelistType=, additionalTags=) classpath中要有jsoup包
主要区分下@NotNull @NotEmpty @NotBlank 3个注解的区别:
@NotNull 任何对象的value不能为null,通常用在基本类型上
@NotEmpty 用在集合类上面 集合对象的元素不为0,即集合不为空,也可以用于字符串不为null
@NotBlank 用在String上面 只能用于字符串不为null,并且字符串trim()以后length要大于0
使用
在实体类的属性中添加注解。
之后在统一异常处理类中,进一步解析异常,返回前台信息:
1 | /** |
控制器中,直接在对应bean上增加注解@Valid
具体分析如下:
1、简单的demo 配置校验
1 |
|
资源文件内容如:
notnull=该字段不能为空
验证的model里面对字段进行验证
@NotBlank(message = "{notnull}")
private String name;
使用,加入注解即可@Valid
1 | public void demo(@Valid Demo demo, BindingResult result){ |
通常不在控制器方法中写BindingResult,统一放到类去处理,如上面的统一异常处理类。
2、hibernate的校验模式
普通模式(默认是这个模式):会校验完所有的属性,然后返回所有的验证失败信息;快速失败返回模式:只要有一个验证失败,则返回。
1 |
|
3、hibernate的两种校验
请求参数校验和GET参数校验
请求参数校验,在控制器方法中加注解 @Valid,然后后面加BindindResult,有多个参数对应加多个注解和BindindResult
GET参数校验(@RequestParam参数校验)
如果是参数较少的情况下:
public void demo(@RequestParam int grade,@RequestParam int classroom) {}
使用@Valid注解,对RequestParam对应的参数进行注解,是无效的,需要使用@Validated注解来使得验证生效。
需要使用MethodValidationPostProcessor 的Bean:
1 |
|
使用:在控制器上加上注解,方法参数直接使用校验规则
1 |
|
统一处理验证不通过的信息
1 | .class) (ConstraintViolationException |
4、实体对象校验
实体类中的属性增加对应的规则
方法中可以通过代码直接校验对象
1 | Set<ConstraintViolation<Demo>> violationSet = validator.validate(demo); |
5、对象联级校验
对象内部包含另一个对象作为属性,属性上加@Valid,可以验证作为属性的对象内部的验证:
@Valid
private Demo demo;
校验方式和上面一致。
6、分组校验
分组顺序校验时,按指定的分组先后顺序进行验证,前面的验证不通过,后面的分组就不行验证。
设置validator为普通验证模式(”hibernate.validator.fail_fast”, “false”)
两个组GroupA、GroupB:
public interface GroupA {}
public interface GroupB {
}
实体类:
1 |
|
GroupA验证字段userId;
GroupB验证字段userName、sex;
Default验证字段age(Default是Validator自带的默认分组)
1 | public void demo5(){ |
如果在参数中使用bean,加入注解即可:@Validated({GroupA.class, GroupB.class})
如果使用组验证顺序:
@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {
}
定义好,使用时,直接用GroupOrder
7、自定义验证器
1 | /** |
实现:
1 | public class ValidatorDemo implements ConstraintValidator<ValidateDemo, Student> { |
这样就可以直接使用@ValidateDemo在属性或者参数上校验,类似@NotBlank,@Max一样的使用方式。
参考:http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html_single/#validator-gettingstarted
以上是Hibernate Validator校验方式,一般还可以用拦截器实现,比如创建一个校验注解来实现(针对单一参数)
1 | //参数级别 ({ElementType.PARAMETER}) |
这样就可以在控制器方法上对应参数加上注解即可。
还有一些spring mvc一定定义好的一些异常,通过统一处理异常的方式去校验参数。
1 | //参数类型不匹配 |
代码见:
https://github.com/huingsn/tech-point-record.git中的springboot-validation-demo