Spring 捕捉校验参数异常并统一处理
使用 @Validated ,@Valid ,@NotBlank 之类的,请自行百度,本文着重与捕捉校验失败信息并封装返回出去
参考:
https://mp.weixin.qq.com/s/EaZxYKyC4L_EofWdtyBCpw
https://www.jianshu.com/p/bcc5a3c86480
捕捉校验失败异常信息
@ControllerAdvice public class WebExceptionHandler {
//处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常,详情继续往下看代码 @ExceptionHandler(BindException.class) @ResponseBody public ResponseVO BindExceptionHandler(BindException e) { String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining()); return new ResponseVO(message); } //处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public ResponseVO ConstraintViolationExceptionHandler(ConstraintViolationException e) { String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining()); return new ResponseVO(message); } //处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。 @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public ResponseVO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) { String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining()); return new ResponseVO(message); } }
如下示例请求参数报错的话,会抛出 BindException 而不是 ConstraintViolationException 和 MethodArgumentNotValidException
@RestController @RequestMapping("test") public class TestController { @GetMapping("refund") public ResponseVO refund(@Valid RefundRequest request) throws Exception { return new ResponseVO(); } } @Data public class RefundRequest implements Serializable { @NotBlank(message = "订单号不能为空") private String orderId; @Min(value = 0, message = "已消费金额金额不能为负数") private int orderAmt; }
如果多个请求参数都校验失败,则遇到第一个校验失败就抛出异常,接下来的异常参数不做校验,配置如下
@Configuration public class WebConfig { @Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() //failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验。 .failFast(true) .buildValidatorFactory(); return validatorFactory.getValidator(); } @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor(); methodValidationPostProcessor.setValidator(validator()); return methodValidationPostProcessor; } }