Spring 捕捉校验参数异常并统一处理

本文介绍如何在Spring MVC中使用@ControllerAdvice进行全局异常处理,包括处理请求参数格式错误、@Valid验证失败等异常,并通过示例展示了如何配置Validator实现failFast功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:https://www.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;
    }
}
 

### 配置Spring MVC中的参数校验 #### 使用Hibernate Validator作为JSR 303的实现 为了在Spring MVC应用程序中启用参数校验,首先需要引依赖项。对于基于Maven构建工具的应用程序,在`pom.xml`文件中添加如下依赖: ```xml <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.2.0.Final</version> </dependency> <!-- 如果使用的是Spring Boot,则可以简化为 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> ``` 上述配置确保了项目能够利用Hibernate Validator来执行bean级别的约束验证[^3]。 #### 启用全局异常处理 当控制器接收到的数据不符合预期时,Spring会自动抛出`MethodArgumentNotValidException`或`ConstraintViolationException`等类型的异常。因此建议设置一个统一异常处理器来捕获友好地响应客户端请求。可以在任意组件类中标记`@ControllerAdvice`注解创建这样的处理器: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Object> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) ->{ String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } } ``` 这段代码展示了如何捕捉到由表单提交或其他HTTP POST/PUT操作引发的有效性错误,返回给前端用户易于理解的信息格式[^4]。 #### 应用场景实例——注册新用户 假设有一个简单的用户实体模型User.java: ```java import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; public class User { @NotBlank(message="用户名不能为空") private String username; @Email(message="邮箱地址不合法") private String email; // getter setter methods... } ``` 接着在一个RESTful风格的服务端点里接收此对象作为之一: ```java @RestController @RequestMapping("/users") public class UserController { @PostMapping("") public void createUser(@RequestBody @Validated User user){ System.out.println("Creating a new user..."); } } ``` 这里特别指出的是`@Validated`和`@Valid`两个注解的选择。前者允许更细粒度控制分组验证逻辑;而后者则更为通用适用于大多数情况下的基本字段级检验需求[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值