Spring 集成Javax Validation 和 Hibernate Validator

Contents
当需要在 controller 层对参数进行验证的时候,可以基于 javax-validation 的注解,结合 hibernate-validator 的验证实现器,以实现参数的校验。Spring 的官方文档参考
如果是使用 springboot 的小伙伴,则更加简便,因为 springboot 的 starter-web本身已经集成了 hibernate-validator 的依赖,因为只需要引入 javax-validation 的依赖即可。
Spring 集成 javax-validation
我们项目用的 Spring 版本是 5.3.x,javax-validation 的版本是 2.0.1.Final。
在没有 hibernate-validator 的情况下,需要在 controller显式声明 BindingResult 这个参数,用于捕获验证结果,以下是一个例子:
public class User {
@NotNull
private String id;
//gettter and setter...
}
@RestController
public class UserController {
@GetMapping(path = "/test")
public void test(@RequestBody @Validated User user, BindingResult result) {
if (result.hasErrors()) {
// process error..
}
}
}
Spring 集成 javax-validation 和 hibernate-validator
显然,这样的错误处理太 hard code 了,并且会导致大量的重复代码,因此,需要引入 hibernate-validator 的依赖,我的版本是5.0.1.Final,它会自动捕获错误,并抛出异常。 以下是一个例子:
@Validated
@RestController
public class UserController {
@GetMapping(path = "/test")
public void test(@RequestBody @Valid User user) {
// service call
}
}
基于 hibernate 的验证处理,当验证失败的时候,会自动抛出一个异常:MethodArgumentNotValidException
,可以看下这个异常继承了BindingException
类,
public class MethodArgumentNotValidException extends BindException
BindingException
类又实现了BindingResult
接口,重写了 getMessage方法,来拼接 BindingResult 中得到的信息
public class BindException extends Exception implements BindingResult {
@Override
public String getMessage() {
StringBuilder sb = new StringBuilder("Validation failed for argument [")
.append(this.parameter.getParameterIndex()).append("] in ")
.append(this.parameter.getExecutable().toGenericString());
BindingResult bindingResult = getBindingResult();
if (bindingResult.getErrorCount() > 1) {
sb.append(" with ").append(bindingResult.getErrorCount()).append(" errors");
}
sb.append(": ");
for (ObjectError error : bindingResult.getAllErrors()) {
sb.append('[').append(error).append("] ");
}
return sb.toString();
}
}
当验证错误都统一捕获并抛出特定异常之后,我们就可以结合Spring 的 @RestControllerAdvice
,对抛出的异常统一处理,这里不多做介绍了。