Spring Boot - Validation 不生效不管用
引入说明
file:[pom.xml]
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
使用位置
通过 @Validated
注解让校验生效,你可以在以下示例的地方开启。
类
在某个类下面,例如 Controller 上面添加这个注解。
lit:[@Validated]:lit
@RestController("/api/auth")
public class AuthController {
}
参数
在函数参数上添加注解。
@GetMapping("/aks-mail-verify-code")
lit:[public Vo askMailVerifyCode(@Validated @RequestParam @Email(message = "不是一个合法的电子邮箱地址") String email,
@Validated @RequestParam @Pattern(regexp = "(register|login|reset)", message = "发送验证码的类型是 register 或 login 或 reset") String type,]:lit
HttpServletRequest http) {
return service.getMailVerifyCode(email, type, HttpUtil.getIpAddr(http));
}
函数
在函数上面添加注解。
lit:[@Validated]:lit
@GetMapping("/aks-mail-verify-code")
public Vo askMailVerifyCode(@RequestParam @Email(message = "不是一个合法的电子邮箱地址") String email,
@RequestParam @Pattern(regexp = "(register|login|reset)", message = "发送验证码的类型是 register 或 login 或 reset") String type,
HttpServletRequest http) {
return service.getMailVerifyCode(email, type, HttpUtil.getIpAddr(http));
}
使用位置的问题
最推荐的位置是在函数参数上添加这个注解,经过我后续一段时间使用经历来看,加在类上或者函数上非常有可能不生效的情况。
还有就是,@Valid
和 @Validate
注解都可以用,建议使用 Spring Boot 提供的 @Validate
。
异常处理的问题
还有一种可能是你没有给完异常处理,这个校验会有三种异常 MethodArgumentNotValidException
、ValidationException
、ConstraintViolationException
。以下是我的全局异常捕获处理:
file:[exception/GlobalExceptionHandler.java]
@Slf4j
@RestControllerAdvice
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler implements Serializable {
/**
* 处理请求参数格式错误 @RequestBody 上使用 @Valid 实体上使用 @NotNull 等,验证失败后抛出的异常是 MethodArgumentNotValidException
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public R<Object> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
log.error(e.getMessage(), e);
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return R.error(message);
}
/**
* 处理 Get 请求中 使用 @Valid 验证路径中请求实体校验失败后抛出的异常
*/
@ExceptionHandler(BindException.class)
public R<Object> BindExceptionHandler(BindException e) {
log.error(e.getMessage(), e);
String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
return R.error(message);
}
/**
* 处理请求参数格式错误 @RequestParam 上 @Validate 失败后抛出的异常是 ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public R<Object> ConstraintViolationExceptionHandler(ConstraintViolationException e) {
log.error(e.getMessage(), e);
String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
return R.error(message);
}
/**
* 参数格式异常
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public R<Object> HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage(), e);
}
}
第一次引入问题
如果你的 Idea 开启了热加载,第一次引入包之后,需重新运行。