做开发的应该都写过类似的校验方法,最简单的判断null,复杂一点的字符串正则校验。单纯从逻辑上说这类代码不复杂,但是有没有一种可能假如需要一次性判断多个,再加上判断失败后的处理逻辑,还有可能需要一些特殊处理,比如正则校验,等等,三个一下,写写也还行,五个以上,如果代码按行收费的话,那能够狠狠的赚了一笔。
大家脑海里的代码可能是这样
这只是一个,实际开发中有些录入非常复杂的表单数据时可能有三四十个,上面我写的处理逻辑也不复杂,真实中可能有些需要使用异常提示,有些需要直接return返回信息,等等,复杂且难以维护。难以维护,到并不是不能维护,钱给的够多,维护,也还是能维护的,当然这个杠不能这样抬。🤣😂😂😂
介绍一个工具,应该说是一套工具,基于注解和反射。
看到这两个词,性能有所损耗是很正常的,比如我们开发全员Map,其实代码的运行速度来说,不慢,但是总所周知HASH(哈希)表是一种非常耗内存的数据结构,所以代码在本地跑的时候时不时的omm异常一下也是合符情理的一件事。😁😁,现在这硬件发展的环境,应该不缺内存这东西。
validation是什么
框架名字叫javax.validation,它提供了一系列的注解来进行对JavaBean的参数校验。通常用来处理Controller里面方法的参数的校验。就是暴露出去的API,内部的方法也可以用,但没必要,暴露出去的接口获取的数据是不可控的,所以才需要校验,内部的数据是可控的,当然内部方法可控的前提是源头的数据是可控的。
安装
springboot中有些博客中写的是这个依赖默认包含在starter-web中了,不清楚从哪个版本开始就不包含在其中了,就说现在的环境是springboot2.5.x系列的,validation默认已经不包含在starter-web中了,需要单独引入这个依赖。
在其他项目中可以引入这个依赖,并自己调整版本即可使用。
注解说明
验证注解 |
验证的数据类型 |
说明 |
@AssertFalse |
Boolean,boolean |
验证注解的元素值是false |
@AssertTrue |
Boolean,boolean |
验证注解的元素值是true |
@NotNull |
任意类型 |
验证注解的元素值不是null |
@Null |
任意类型 |
验证注解的元素值是null |
@Min(value=值) |
BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型 |
验证注解的元素值大于等于@Min指定的value值 |
@Max(value=值) |
和@Min要求一样 |
验证注解的元素值小于等于@Max指定的value值 |
@DecimalMin(value=值) |
和@Min要求一样 |
验证注解的元素值大于等于@ DecimalMin指定的value值 |
@DecimalMax(value=值) |
和@Min要求一样 |
验证注解的元素值小于等于@ DecimalMax指定的value值 |
@Digits(integer=整数位数, fraction=小数位数) |
和@Min要求一样 |
验证注解的元素值的整数位数和小数位数上限 |
@Size(min=下限, max=上限) |
字符串、Collection、Map、数组等 |
验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小 |
@Past |
java.util.Date,java.util.Calendar;Joda Time类库的日期类型 |
验证注解的元素值(日期类型)比当前时间早 |
@Future |
与@Past要求一样 |
验证注解的元素值(日期类型)比当前时间晚 |
@NotBlank |
CharSequence子类型 |
验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首位空格 |
@Length(min=下限, max=上限) |
CharSequence子类型 |
验证注解的元素值长度在min和max区间内 |
@NotEmpty |
CharSequence子类型、Collection、Map、数组 |
验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@Range(min=最小值, max=最大值) |
BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型 |
验证注解的元素值在最小值和最大值之间 |
@Email(regexp=正则表达式,flag=标志的模式) |
CharSequence子类型(如String) |
验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式 |
@Pattern(regexp=正则表达式,flag=标志的模式) |
String,任何CharSequence的子类型 |
验证注解的元素值与指定的正则表达式匹配 |
@Valid |
任何非原子类型 |
指定递归验证关联的对象如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证 |
这里只列出Hibernate Validator提供的大部分验证约束注解,如需了解更多请参考hibernate validator官方文档了解其他验证约束注解和进行自定义的验证约束注解定义。这块内容基本就是翻译文档,没啥好说的。
实际使用
DTO 上的注解
全局异常处理
参数校验失败时会报异常,但是把异常直接显示给用户是非常不友好的,于是需要全局处理一下异常。
默认异常信息
全局异常拦截器
自定义参数注解
如果默认的注解不够用,你还可以自定义注解,比如一个身份证号的验证
注解
自定义Validator
这里才是才是真正的处理逻辑,注解类似是一个徽章,在AOP处理处理时,是一个特殊的标识。
使用
使用groups的校验
就是分组校验,一个实体类作为不同的接口参数校验时,可能有不同的需求。定义两个接口。
再在需要校验的地方@Validated声明校验组
DTO 改一下
tips 注意:在声明分组的时候尽量加上 extend javax.validation.groups.Default
否则,在你声明@Validated(Update.class)
的时候,就会出现你在默认没添加groups = {}
的时候的校验组@Email(message = "邮箱格式不对")
,会不去校验,因为默认的校验组是groups = {Default.class}
restful风格用法
在多个参数校验,或者@RequestParam 形式时候,需要在controller上加注@Validated
需要加上
说了一大通基础的东西,但是感觉其实挺全面了,各种用法都介绍了,不足就是 但是没有很深入,如异常的日志的记录,等等。
封面