场景:
MVC的三层框架中,在Controller层传对象后(一般是xxVO),经常需要对该对象进行参数校验,非空、长度等。但这些代码会大量重复,非常冗余。因此我们把相应处理提取,直接在对象上用注解实现功能
其中JSR-303
就是比较常用的一种。
导入依赖:(此处为springboot环境)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
使用参考:Validator验证
其中 @Valid、@Validated
,就表示开启参数验证
有两种用法:
-
用
BindingResult
存储错误信息/** (借用上文中的代码作为例子) 1. @Validated表明参数user是要校验的类,BindingResult是存储错误信息的类, 2. 两者必须一一对应,并且位置挨着,不能中间有其他参数 */ @RequestMapping(value = "/login",method = RequestMethod.POST) public String login(@Validated User user, BindingResult br){ if (br.hasErrors()){ return "user/login"; } return "--"; }
-
不直接处理。因为显然,这也是与Controller无关的逻辑,提高了耦合性。
因此我们经常不用第一种,而是直接不处理:
如果校验不通过,会产生BindException异常
然后通过全局异常处理它。核心:
@ControllerAdvice + @ExceptionHandler
具体用法请自行百度,本文不再赘述
小拓展:
问:当同时使用两者时,哪种会生效?
答:第一种,因为第一种就是捕获了异常封装在BindResult中,也就没有抛出异常的操作
值得一提的是,自定义注解中的message、groups、payload
三个属性是必须定义的,缺任一都会报错:javax.validation.ConstraintDefinitionException: HV000074
笔者本来以为是
@Validated
支持分组才需要,@Valid
不支持应该是不需要的。但经实际测试,两者都会报错,因此这三个参数确实是必须的
本文完,有误欢迎指出