JSR-303(Bean Validation) 处理 数据校验的。
声明式注解:让代码简洁直观。
与框架无缝集成:特别是 Spring,使得校验变得非常简单。
强大的扩展性:支持分组和自定义注解,满足复杂业务需求。
1. 它解决了什么问题?
在没有 JSR-303 之前,我们通常这样写校验:
public String createUser(User user) {
// 手动校验
if (user.getName() == null || user.getName().isEmpty()) {
return "用户名不能为空";
}
if (user.getAge() < 0 || user.getAge() > 150) {
return "年龄不合法";
}
if (user.getEmail() == null || !isValidEmail(user.getEmail())) {
return "邮箱格式错误";
}
// ... 更多的 if-else
// 如果校验通过,才执行业务逻辑
userService.save(user);
return "成功";
}
这种方式的问题:
- 代码冗余:每个需要校验的方法都要写大量重复的校验代码。
- 不易维护:校验规则分散在各个角落,修改规则需要找到所有相关代码。
- 耦合性高:校验逻辑和业务逻辑混杂在一起。
2. JSR-303 是如何工作的?
使用 JSR-303,你只需要两步:
第一步:在 Java Bean 的属性上添加校验注解
java
// 注意:这里使用的是 Jakarta EE(或 Javax)的注解
public class User {
@NotBlank(message = "用户名不能为空")
private String name;
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
@Email(message = "邮箱格式不正确")
private String email;
// ... 省略 getter 和 setter
}
第二步:在需要校验的方法参数前使用 @Valid 注解
在 Spring 框架中,你通常在 Controller 层使用它:
@RestController
public class UserController {
@PostMapping("/users")
public ResponseEntity<String> createUser(@RequestBody @Valid User user) {
// 当请求到达这个方法时,Spring 会自动对 user 对象进行校验
// 如果校验失败,会直接抛出 MethodArgumentNotValidException,而不会执行下面的业务代码
userService.save(user);
return ResponseEntity.ok("用户创建成功");
}
}
3. 常用的校验注解
JSR-303 提供了一系列内置注解,在 jakarta.validation.constraints(或 javax.validation.constraints)包下:
| 注解 | 说明 | 支持的数据类型 |
|---|---|---|
@NotNull | 值不能为 null | 任意类型 |
@Null | 值必须为 null | 任意类型 |
@NotBlank | 字符串不能为 null,且必须包含至少一个非空白字符 | String |
@NotEmpty | 值不能为 null 或空(集合/数组/Map的大小>0,字符串长度>0) | String, Collection, Map, Array |
@Size(min=, max=) | 检查字符串、集合、数组的大小是否在指定范围内 | String, Collection, Map, Array |
@Min(value) | 数字值必须大于或等于指定的最小值 | BigDecimal, BigInteger, 数值类型 |
@Max(value) | 数字值必须小于或等于指定的最大值 | BigDecimal, BigInteger, 数值类型 |
@DecimalMin(value) | 同 @Min,但可以用于字符串表示的数字 | 同 @Min, String |
@DecimalMax(value) | 同 @Max,但可以用于字符串表示的数字 | 同 @Max, String |
@Email | 字符串必须是合法的电子邮件地址 | String |
@Pattern(regex=) | 字符串必须匹配指定的正则表达式 | String |
@Positive | 数字必须是正数 | 数值类型 |
@PositiveOrZero | 数字必须是正数或零 | 数值类型 |
@Negative | 数字必须是负数 | 数值类型 |
@NegativeOrZero | 数字必须是负数或零 | 数值类型 |
@Future | 日期必须在将来 | 日期类型 |
@FutureOrPresent | 日期必须在将来或现在 | 日期类型 |
@Past | 日期必须在过去 | 日期类型 |
@PastOrPresent | 日期必须在过去或现在 | 日期类型 |