java jsr-303 validate 数据校验

35 阅读3分钟

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)StringCollectionMapArray
@Size(min=, max=)检查字符串、集合、数组的大小是否在指定范围内StringCollectionMapArray
@Min(value)数字值必须大于或等于指定的最小值BigDecimalBigInteger, 数值类型
@Max(value)数字值必须小于或等于指定的最大值BigDecimalBigInteger, 数值类型
@DecimalMin(value)同 @Min,但可以用于字符串表示的数字同 @MinString
@DecimalMax(value)同 @Max,但可以用于字符串表示的数字同 @MaxString
@Email字符串必须是合法的电子邮件地址String
@Pattern(regex=)字符串必须匹配指定的正则表达式String
@Positive数字必须是正数数值类型
@PositiveOrZero数字必须是正数或零数值类型
@Negative数字必须是负数数值类型
@NegativeOrZero数字必须是负数或零数值类型
@Future日期必须在将来日期类型
@FutureOrPresent日期必须在将来或现在日期类型
@Past日期必须在过去日期类型
@PastOrPresent日期必须在过去或现在日期类型