什么是java的JSR 380?

一、介绍

JSR 380 是 Java 规范请求(Java Specification Request) 中定义的一套 Bean 校验标准,全称《Bean Validation 2.0》,核心目标是:为 Java Bean(如 DTO、实体类)提供统一的参数校验注解和 API,避免重复编写校验逻辑

简单说:JSR 380 就是一套 “标准化的参数校验注解”,比如 @NotNull(非空)、@Size(长度限制)、@Email(邮箱格式),配合校验框架(如 Hibernate Validator),能自动完成参数合法性校验,无需手动写 if (param == null) { throw ... }

二、定位

  • 解决问题:避免每个服务 / 接口都重复编写参数校验逻辑(如非空、格式、范围校验),统一校验规则和错误提示;
  • 本质:一套接口规范(定义注解和核心 API),需依赖具体实现框架(最常用的是 Hibernate Validator,是 JSR 380 的官方参考实现);
  • 适用场景:Java Bean 的参数校验(如 Feign 调用的 DTO、Controller 接口参数、数据库实体类等)。

三、特性

  1. 标准化注解:定义了一系列通用校验注解,无需自定义,直接标注在 Bean 字段上即可;
  2. 声明式校验:通过注解声明校验规则,无需编写硬编码校验逻辑,代码更简洁;
  3. 自动校验:配合 Spring Boot 等框架,可自动触发校验(如 Controller 接口入参、Feign 调用参数),校验失败自动抛出异常;
  4. 可扩展:支持自定义校验注解(如 @Phone 手机号校验),满足业务特殊需求。

四、常用核心注解(JSR 380 标准注解)

注解 作用 示例
@NotNull 字段不能为 null(但可以是空字符串 “”) @NotNull(message = "用户ID不能为空")
@NotBlank 字符串不能为 null 且不能是空白(空格、空串) @NotBlank(message = "用户名不能为空")
@NotEmpty 集合 / 数组 / 字符串不能为 null 且长度 > 0 @NotEmpty(message = "标签列表不能为空")
@Size(min, max) 字符串长度 / 集合大小在 [min, max] 之间 @Size(min=2, max=20, message = "用户名长度2-20字")
@Min(value) 数字(int/long 等)最小值 @Min(value=18, message = "年龄不能小于18")
@Max(value) 数字最大值 @Max(value=120, message = "年龄不能大于120")
@Email 字符串必须是合法邮箱格式 @Email(message = "邮箱格式不正确")
@Pattern(regexp) 字符串匹配正则表达式 @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
@Past 日期必须是过去的时间(如生日) @Past(message = "生日必须是过去的时间")
@Future 日期必须是未来的时间(如预约时间) @Future(message = "预约时间必须是未来的时间")
@Positive 数字必须为正数 @Positive(message = "金额必须为正数")

五、使用(Spring Boot + JSR 380)

1. 引入依赖(Spring Boot 已集成 Hibernate Validator)

Spring Boot 2.x+ 自带 Hibernate Validator(JSR 380 实现),无需额外引入依赖;若缺失,手动添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 在 DTO 中添加校验注解
// Feign 调用或 Controller 接收的 DTO
public class UserDTO {
    @NotNull(message = "用户ID不能为空")
    private Integer id;

    @NotBlank(message = "用户名不能为空")
    @Size(min = 2, max = 20, message = "用户名长度2-20字")
    private String name;

    @Email(message = "邮箱格式不正确")
    private String email;

    @Min(value = 18, message = "年龄不能小于18")
    private Integer age;

    // getter/setter
}
3. 触发校验(自动校验)

Controller 接口参数校验:添加 @Valid@Validated 注解,触发自动校验:

@PostMapping("/user")
public String addUser(@Valid @RequestBody UserDTO userDTO) {
    // 校验通过则执行业务逻辑,失败则抛出 MethodArgumentNotValidException
    return "success";
}

Feign 调用参数校验:在 Feign 接口添加 @Validated,DTO 字段添加注解即可:

// Feign 接口
@FeignClient(name = "user-service")
@Validated // 开启 Feign 参数校验
public interface UserFeignClient {
    @GetMapping("/user/info")
    UserVO getUserInfo(@Valid UserDTO userDTO); // DTO 字段的注解会生效
}
4. 统一处理校验异常

通过 Spring 全局异常处理器,捕获校验失败的异常,返回统一格式的错误信息:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleValidException(MethodArgumentNotValidException e) {
        // 提取所有校验失败的错误信息
        List<String> errors = e.getBindingResult().getFieldErrors().stream()
                .map(error -> error.getField() + ":" + error.getDefaultMessage())
                .collect(Collectors.toList());
        return Result.fail("参数校验失败", errors);
    }
}

六、补充

  • JSR 380 是 “规范”,Hibernate Validator 是 “实现”:就像 JPA 是规范,Hibernate 是实现一样,实际开发中用的是 Hibernate Validator 的具体功能(完全兼容 JSR 380);

  • 支持嵌套校验:若 DTO 包含嵌套对象(如 UserDTO 包含 AddressDTO),在嵌套字段上添加 @Valid 即可触发嵌套校验:

    简单说明一下规范和实现的关系:菜谱(规范) vs 厨师做菜(实现)

    JSR 380(规范)= 一份 “宫保鸡丁官方菜谱”:

    只写清楚 “做宫保鸡丁的标准要求”—— 比如必须有鸡肉、花生、干辣椒,要炒至鸡丁断生、酸甜咸辣平衡,不能少关键步骤。但菜谱不会动手帮你做,也不规定具体用哪种牌子的酱油、炒多久(只给核心标准)。

    Hibernate Validator(实现)= 餐厅里按菜谱做菜的厨师:

    厨师完全照着菜谱的 “标准要求” 来做(满足规范),但会补充具体细节 —— 比如用海天酱油、大火炒 3 分钟、花生炸至金黄。你吃的 “能直接入口的宫保鸡丁”(实际开发中用的校验功能),是厨师做出来的,而不是菜谱本身。

    其他实现(比如 Apache BVal,也是 JSR 380 实现),就像另一位厨师 —— 同样按这份宫保鸡丁菜谱做(符合规范),但可能用李锦记酱油、中火炒 4 分钟,口味略有差异,但核心是 “符合菜谱标准” 的宫保鸡丁。

    JSR 380 画了个 “参数校验该怎么做” 的蓝图,Hibernate Validator 照着蓝图造出了 “能直接用的校验工具”

public class UserDTO {
    // ... 其他字段
    @Valid // 触发 AddressDTO 内部的校验注解
    @NotNull(message = "地址不能为空")
    private AddressDTO address;
}

public class AddressDTO {
    @NotBlank(message = "城市不能为空")
    private String city;
}
  • 支持自定义注解:若标准注解满足不了业务(如手机号校验),可自定义校验注解(基于 JSR 380 扩展)。

七、总结

JSR 380 是 Java 生态中参数校验的 “标准方案”,通过标准化注解 + 自动校验,解决了重复校验、规则不统一的问题,是服务间通信(如 Feign 调用)、接口参数校验的必备工具,配合 Spring Boot 可快速集成使用。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐