平时开发中遇到的问题,大部分已经有了答案,但需要去寻找
前言
java在很早(2009)就出现了校验规范Bean Validation,并且经历了几次标准的迭代,版本的历史就不去深究了。
Bean Validation 只是提供了校验规范和一些注解,并没有提供实现,而Hibernate Validator对其所有的constraint进行了实现,并增加了一些自定义的constraint。
spring-boot-starter-validation
(新版本的starter-web不包含该依赖,需单独添加)对Hibernate Validator
进行了封装,使其可以在spring mvc模块进行自动校验
除了接下来分析的Spring Validation, 一些规则引擎也具备校验功能,可以参考。
开始
区别 | @Valid | @Validated |
---|---|---|
提供者 | Javax | Spring Validation |
分组 | 不支持 | 支持 |
嵌套 | 支持 | 不支持 |
注解位置 | 类、属性、构造方法、方法参数 、类型 | 类、方法、方法参数 |
-
封装型的请求参数校验
在实体类的属性上使用相关约束的注解
然后在controller的方法上对要校验的参数使用@Valid
或@Validated
进行标注@GetMapping("analysis") public List<ColumnChangDetail> analysis(@Valid AnalysisForColumnVO req) { return analysisService.analysisForColumn(req); }
发生请求时,若校验失败则会抛出指定的异常,可使用全局统一异常处理类中处理此类异常
异常 校验失败场景 BindException form-data MethodArgumentNotValidException application/json ConstraintViolationException 单个参数 -
平铺型的请求参数校验
如果请求参数没有使用实体类封装,则需要在Controller类上标注@Validated,否则不生效@RestController @RequestMapping("demo") @RequiredArgsConstructor @Validated public class DemoController { private final DemoService demoService; @GetMapping("{id}") public DemoVO getDetail(@Max(10) @PathVariable("id") Long id) { return demoService.getDetail(id); } }
Bean Validation内置约束
被注解标注的属性的数据类型通常是有限制的,比如
@Digits
标注的变量类型必须是数字,若是放在了Strinig
类型的变量上,在运行时会发生异常。
这种细节问题容易造成不易发现的bug,那有没有一种机制可以在编译时提醒这种错误的用法呢,还真有hibernate-validator-annotation-processor
,添加这个依赖,会在编译期间检查这些约束是否使用得当并提示。
Hibernate Validation扩展约束
分组
同样的参数在不同的场景下可能有不同的校验规则,这时可以使用分组校验。
嵌套
快速失败
当有多个参数校验时,它不会在发现第一个校验失败后停止,而是继续校验,直到发现所有的错误