Spring 是如何捕捉校验参数异常并处理的?

程序员考拉

共 2880字,需浏览 6分钟

 ·

2020-07-29 18:56

出处:cnblogs.com/fqybzhangji/p/10384347.html


使用 @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;
    }
}




如果觉得不错点个“在看”哟!

浏览 6
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报