参数校验Spring的@Valid注解用法解析
参数校验Spring的@Valid注解
@Valid 注解通常用于对象属性字段的规则检测。
以新增一个员工为功能切入点,以常规写法为背景,慢慢烘托出 @Valid 注解用法详解。
那么,首先,我们会有一个员工对象 Employee,如下 :
public class Employee { /** 姓名 */public String name; /** 年龄 */public Integer age; public String getName() {return name; } public void setName(String name) {this.name = name; } public Integer getAge() {return age; } public void setAge(Integer age) {this.age = age; } }
然后 Cotroller 中会有一个对应都新增方法 add():
@Controllerpublic class TestController { @RequestMapping("/add")@ResponseBodypublic String add(Employee employee) {// TODO 保存到数据库return "新增员工成功"; } }
需求变更,要求员工名称不能为空,且长度不超过10个字符
我们的原始写法:
文章图片
现在规定年龄也是必填项,且范围在1到100岁,那么此时,我们需要增加判定
文章图片
现在员工对象 Employee 就 2 个字段,我们就写了 10 多行的代码验证,要是有20个字段,岂不是要写 100 多行代码?
如何解决呢?
将验证过程抽成一个验证方法:
文章图片
但这种方式只是抽了一个方法,有一种换汤不换药的感觉,虽然业务方法看起来清爽了很多,但书写代码量并没有下降,反而还多出了一个方法。
此时引出 Spring 的 @valid 注解即可:
首先,我们在 Maven 配置中引入 @valid 的依赖:
如果你是 springboot 项目,那么可以不用引入了,已经引入了,他就存在于最核心的 web 开发包里面。
org.springframework.boot spring-boot-starter-web2.0.5.RELEASE
代码优化
首先在 Employee 类的属性上打上如下注解:
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Range; public class Employee { /** 姓名 */@NotBlank(message = "请输入名称")@Length(message = "名称不能超过个 {max} 字符", max = 10)public String name; /** 年龄 */@NotNull(message = "请输入年龄")@Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)public Integer age; public String getName() {return name; } public void setName(String name) {this.name = name; } public Integer getAge() {return age; } public void setAge(Integer age) {this.age = age; } }
然后再 Controller 对应方法上,对这个员工标上 @Valid 注解,表示我们对这个对象属性需要进行验证
文章图片
用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult:
文章图片
对应获取验证结果的代码如下:
文章图片
@Valid与@Validated注解 之前项目中参数的校验,都是自己写的判断方法进行校验,这次采用了spring提供的注解进行参数的校验,更为的方便,简洁。
@Valid:常见用在方法,类中字段上进行校验
文章图片
文章图片
@Validated:是spring提供的对@Valid的封装,常见用在方法上进行校验
文章图片
定义的校验类型
@Null
验证对象是否为null@NotNull
验证对象是否不为null, 无法查检长度为0的字符串@NotBlank
检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.@NotEmpty
检查约束元素是否为NULL或者是EMPTY.@CreditCardNumber
信用卡验证@Email
验证是否是邮件地址,如果为null,不进行验证,算通过验证。@URL
(protocol=,host=, port=,regexp=, flags=) ip地址校验Booelan检查
@AssertTrue
验证 Boolean 对象是否为 true【参数校验Spring的@Valid注解用法解析】
@AssertFalse
验证 Boolean 对象是否为 false长度检查
@Size(min=, max=)
验证对象(Array,Collection,Map,String)长度是否在给定的范围之内@Length(min=, max=) Validates that the annotated string is between min and max included.
日期检查
@Past
验证 Date 和 Calendar 对象是否在当前时间之前@Future
验证 Date 和 Calendar 对象是否在当前时间之后@Pattern
验证 String 对象是否符合正则表达式的规则数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为""时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min
验证 Number 和 String 对象是否大等于指定的值@Max
验证 Number 和 String 对象是否小等于指定的值@DecimalMax
被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits
验证 Number 和 String 的构成是否合法@Digits(integer=,fraction=)
验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
注意的几点: (1)如果一个bean中包含第二个bean
这时要检验第二个bean中某个字段,即嵌套校验,必须要在第一个bean对象中使用@Valid标注到表示第二个bean对象的字段上,然后再第二个bean对象里面的字段上加上校验类型
文章图片
文章图片
(2)@Validated支持分组注解
1、先定义一个空接口:GroupA
文章图片
2、对bean对象中校验类型,添加分组信息,这里我对version字段进行了分组校验信息添加
文章图片
3、方法入参中进行分组信息添加
文章图片
文章图片
如上图所示,则shelveProject方法由于添加了分组信息会校验DeleteProjectRequest对象中的version字段是否为空,而offShelveProject方法没有添加分组信息,不会校验version是否为空。
@Validated没有添加groups属性时,默认验证没有分组的验证属性。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- Jsr303做前端数据校验
- [源码解析]|[源码解析] NVIDIA HugeCTR,GPU版本参数服务器---(3)
- spring|spring boot项目启动websocket
- Spring|Spring Boot 整合 Activiti6.0.0
- 接口|axios接口报错-参数类型错误解决
- Spring集成|Spring集成 Mina