Spring Boot 参数校验-@Valid、@Validated

Spring Boot 参数校验-@Valid、@Validated

📦 依赖引入

pom.xml 中添加以下依赖,启用 Bean Validation:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

🧠 核心注解说明

注解说明
@NotNull不为 null
@NotEmpty不为 null 且不为空
@NotBlank不为 null 且去空格后不为空
@Min / @Max数值大小限制
@Email邮箱格式校验
@Pattern正则表达式校验
@Size长度或集合大小范围
@Valid启用嵌套对象校验
@Validated启用分组校验或方法级校验

✅ @Valid 和 @Validated 区别

特性@Valid@@Validated``
所属包javax.validation.Validorg.springframework.validation.annotation.Validated
分组校验支持❌ 不支持✅ 支持
方法参数校验支持❌ 不支持✅ 支持
嵌套对象校验支持✅ 支持✅ 支持
用于类级方法参数校验❌ 无效✅ 有效

🚀 使用示例

1. 创建 DTO 对象

@Data
public class UserDTO {

    @Size(min = 2, max = 5, message = "用户名长度必须在2~5之间")
    private String username;

    @Email(message = "邮箱格式错误")
    private String email;

    @Min(value = 18, message = "年龄必须 >= 18")
    private Integer age;
}

2. Controller 使用校验

@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping("/create")
    public String createUser(@Valid @RequestBody UserDTO userDTO) {
        return "用户创建成功";
    }
}

3. 全局异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(err ->
            errors.put(err.getField(), err.getDefaultMessage()));
        return ResponseEntity.badRequest().body(errors);
    }
}

🧩 分组校验示例

public class UserDTO {
    public interface Create {}
    public interface Update {}

    @Null(groups = Create.class)
    @NotNull(groups = Update.class)
    private Long id;

    @NotBlank(groups = {Create.class, Update.class})
    private String username;
}
@PostMapping("/add")
public String add(@Validated(UserDTO.Create.class) @RequestBody UserDTO dto) {}

@PostMapping("/update")
public String update(@Validated(UserDTO.Update.class) @RequestBody UserDTO dto) {}

🛠 方法级参数校验

@Validated
@Service
public class UserService {

    public void updateUser(@NotNull(message = "ID不能为空") Long id) {
        // ...
    }
}

✅ 总结

你想做什么推荐使用
基本请求体校验@Valid
分组校验@Validated
Controller / Service 方法参数校验类上加 @Validated

⚠️ 三种常见的参数校验异常说明

1. MethodArgumentNotValidException

  • 出现场景:使用 @Valid @RequestBody 的 DTO 参数校验失败
  • 常用于:JSON 请求体
  • 处理方式
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
    String msg = ex.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
    return ResponseEntity.badRequest().body(msg);
}

2. ConstraintViolationException

  • 出现场景:使用 @Validated@RequestParam / 基础类型参数进行校验
  • 常用于:方法入参、Query参数等
  • 处理方式
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<?> handleConstraintViolation(ConstraintViolationException ex) {
    String msg = ex.getConstraintViolations().iterator().next().getMessage();
    return ResponseEntity.badRequest().body(msg);
}

3. HandlerMethodValidationException(Spring Boot 3 / Spring 6 及以上)

  • 出现场景:方法级参数校验失败(Controller 或 Service)
  • 说明:Spring 6 引入的统一校验异常,封装了多个底层校验异常
  • 处理方式
@ExceptionHandler(HandlerMethodValidationException.class)
public ResponseEntity<?> handleHandlerMethodValidation(HandlerMethodValidationException ex) {
    String msg = ex.getAllValidationResults().get(0).getResolvableErrors().get(0).getDefaultMessage();
    return ResponseEntity.badRequest().body(msg);
}

📌 全局统一处理建议(推荐用于 Spring Boot 3+)

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleInvalid(MethodArgumentNotValidException ex) {
        String msg = ex.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
        return ResponseEntity.badRequest().body(msg);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<?> handleConstraint(ConstraintViolationException ex) {
        String msg = ex.getConstraintViolations().iterator().next().getMessage();
        return ResponseEntity.badRequest().body(msg);
    }

    @ExceptionHandler(HandlerMethodValidationException.class)
    public ResponseEntity<?> handleHandler(HandlerMethodValidationException ex) {
        String msg = ex.getAllValidationResults().get(0).getResolvableErrors().get(0).getDefaultMessage();
        return ResponseEntity.badRequest().body(msg);
    }
}

✅ 异常类型对比总结

异常作用范围出现场景Spring 版本
MethodArgumentNotValidException@RequestBodyDTO 参数校验失败Spring Boot 2/3
ConstraintViolationException基本类型参数方法参数、@RequestParamSpring Boot 2/3
HandlerMethodValidationException方法级统一封装Controller / Service 方法参数Spring Boot 3 / Spring 6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值