摘要
JSR 380 是 Bean Validation 2.0 规范,用注解声明校验规则,省掉 Controller 里的 if-else 判断。本文介绍在 Spring Boot 中引入依赖、在 DTO 上使用 @NotNull/@Size/@Email 等常用注解、用 @Valid 触发校验并统一处理校验异常的完整基础流程。
JSR 380 是 Java 的 Bean Validation 2.0 规范,它提供了一套基于注解的标准来校验 Java 对象中的数据是否合规。在 Spring Boot 中,你通常不需要在 Controller 里写一堆 if-else 来检查参数,而是在 DTO(数据传输对象)的字段上添加校验注解,让框架自动帮你完成。
📦 第一步:引入依赖
Spring Boot 提供了专门的起步依赖,它内置了 Hibernate Validator(JSR 380 的参考实现)。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
✍️ 第二步:在 DTO 上声明校验规则
定义一个接收参数的类,在字段上使用标准注解来声明约束。JSR 380 提供了丰富的内置注解,以下是一些最常用的:
| 注解 | 说明 | 适用类型 |
|---|---|---|
@NotNull | 不能为 null | 任意类型 |
@NotBlank | 字符串不能为 null 且去除首尾空格后长度 > 0 | 字符串 |
@NotEmpty | 不能为 null 且长度/大小 > 0 | 字符串、集合、数组 |
@Size(min, max) | 长度或大小必须在指定范围内 | 字符串、集合、数组 |
@Min(value) / @Max(value) | 数值必须大于等于/小于等于指定值 | 数值类型 |
@Positive / @Negative | 必须是正数 / 负数 | 数值类型 |
@Email | 必须是合法的邮箱格式 | 字符串 |
@Pattern(regexp) | 必须匹配指定的正则表达式 | 字符串 |
@Past / @Future | 必须是过去 / 未来的时间 | 时间类型 (JSR 310) |
import jakarta.validation.constraints.*;
public class UserDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度需在 3-20 之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 8, message = "密码长度至少为 8 位")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 1, message = "年龄必须大于 0")
@Max(value = 120, message = "年龄不能超过 120")
private Integer age;
// getter / setter 省略
}
🎯 第三步:在 Controller 中触发校验
在需要校验的对象参数前加上 @Valid 注解,Spring 就会自动触发校验流程。
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping("/register")
public String register(@Valid @RequestBody UserDTO userDTO) {
// 如果校验失败,代码根本走不到这里,框架会直接抛出异常
return "注册成功";
}
}
⚠️ 第四步(可选):处理校验异常
当校验失败时,Spring 会抛出 MethodArgumentNotValidException。为了给前端返回友好、统一的错误信息,可以添加一个全局异常处理器。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(error ->
errors.put(error.getField(), error.getDefaultMessage())
);
return errors;
}
}
💡 进阶用法
除了校验 @RequestBody,你也可以在 Service 层的方法参数上直接使用校验注解,但需要在类上添加 @Validated 注解:
@Service
@Validated
public class UserService {
public void updateUser(@NotBlank String username, @Min(1) Integer age) {
// 方法参数上的约束会自动生效
}
}
总结
JSR 380 的核心思想是声明式校验:你只需通过注解描述“数据应该长什么样”,框架就会在运行时自动检查。在 Spring Boot 中,配合 @Valid 和全局异常处理,可以极大减少 Controller 层的手写校验代码。
全部评论(0)
还没有任何评论哟~