当前位置: 首页 > backend >正文

Spring Boot 校验分组(Validation Groups)高级用法全指南

Spring Boot 校验分组(Validation Groups)高级用法全指南

版本:Spring Boot 3.x + Jakarta Bean Validation 3.x
目标:用 同一份 DTO 支撑 “新增 / 修改 / 导入 / 审核” 等多套校验规则,零冗余、零硬编码、易扩展


一、为什么需要校验分组?

场景规则差异示例
新增id 必须为 null
修改id 必须非 null
导入批量字段可空,但格式必须合法
审核只校验备注长度,其余忽略

传统写法:为每个场景写独立 DTO → 类爆炸、重复字段、维护困难
分组写法一个 DTO + N 个场景接口按需启用,极致简洁。


二、核心三要素(牢记即可)

要素作用示例
分组接口(Marker Interface)标记场景interface Create {}
分组注解指定规则生效范围@NotNull(groups = Update.class)
分组校验调用时声明场景@Validated(Create.class)

三、快速上手(3 步走)

1️⃣ 定义分组接口

public interface Create {}   // 新增
public interface Update {}   // 修改
public interface Import {}   // 批量导入
public interface Audit {}    // 审核

2️⃣ 在 DTO 上按场景声明规则

@Data
public class UserDTO {// 新增时 id 必须为 null;修改时 id 必须非 null@Null(groups = Create.class)@NotNull(groups = Update.class)private Long id;// 所有场景必填@NotBlank(groups = {Create.class, Update.class, Import.class})private String username;// 仅导入场景校验邮箱格式@Email(groups = Import.class)private String email;// 仅审核场景校验备注长度@Size(max = 500, groups = Audit.class)private String remark;
}

3️⃣ 在 Controller 指定场景

@RestController
@RequestMapping("/user")
@Validated   // 告诉 Spring 启用方法级校验
public class UserController {@PostMappingpublic String create(@Validated(Create.class) @RequestBody UserDTO dto) {return "新增成功";}@PutMapping("/{id}")public String update(@PathVariable Long id,@Validated(Update.class) @RequestBody UserDTO dto) {dto.setId(id);return "修改成功";}@PostMapping("/batch")public String batch(@Validated(Import.class) @RequestBody List<@Valid UserDTO> list) {return "导入成功";}@PostMapping("/{id}/audit")public String audit(@PathVariable Long id,@Validated(Audit.class) @RequestBody UserDTO dto) {dto.setId(id);return "审核成功";}
}

四、高级技巧(生产常用)

1️⃣ 组继承(减少重复注解)

public interface Create extends Default {}  // 继承默认组
public interface Update extends Default {}

默认组 javax.validation.groups.Default 可省略 groups = Default.class

2️⃣ 分组序列(按顺序校验)

@GroupSequence({Create.class, SecondStep.class})
public interface CreateTwoStep {}
  • 先校验 Create 规则 → 通过后继续 SecondStep避免一次性抛出所有错误

3️⃣ 动态分组(运行时决定)

@Component
public class ValidationGroupSelector {public Class<?> resolveGroup(String operation) {return switch (operation) {case "create" -> Create.class;case "update" -> Update.class;case "import" -> Import.class;default -> Default.class;};}
}

在 Service 层使用:

Set<ConstraintViolation<UserDTO>> violations =validator.validate(dto, groupSelector.resolveGroup(operation));

五、与常见框架集成

框架用法
Spring MVC@Validated(Group) + 全局异常处理
Spring BatchItemProcessor 中手动 validator.validate(item, Import.class)
MapStruct映射后调用 validator.validate(dto, Update.class) 确保 DTO 合法

六、避坑清单

解决
默认组未生效显式继承 Default 或显式声明 groups = Default.class
集合参数未生效使用 List<@Valid DTO> + @Validated(Group)
构造器注入构造器参数上同样加 @Validated(Group)

七、一句话总结

“一个 DTO + N 个 Marker 接口”
让 Spring Boot 的 同一份数据模型不同业务场景 下拥有 不同校验规则
彻底告别 DTO 冗余if-else 校验地狱

http://www.xdnf.cn/news/18519.html

相关文章:

  • 从0到1:数据库进阶之路,解锁SQL与架构的奥秘
  • 32位内部数据通路是什么?
  • 基于llama.cpp的量化版reranker模型调用示例
  • 【golang】制作linux环境+golang的Dockerfile | 如何下载golang镜像源
  • 避开MES实施的“坑”:详解需求、开发、上线决胜点
  • openharmony之启动恢复子系统详解
  • Doxygen是什么?
  • Neural Network with Softmax output|神经网络的Softmax输出
  • 深入剖析Spring Boot应用启动全流程
  • 第七章 利用Direct3D绘制几何体
  • flink常见问题之非法配置异常
  • Hive Metastore和Hiveserver2启停脚本
  • jetson ubuntu 打不开 firefox和chromium浏览器
  • Python 实战:内网渗透中的信息收集自动化脚本(2)
  • 嵌入式LINUX——————网络TCP
  • Mysql InnoDB 底层架构设计、功能、原理、源码系列合集【六、架构全景图与最佳实践】
  • ArcGIS Pro 安装路径避坑指南:从崩溃根源到规范实操(附问题修复方案)
  • 在 CentOS 7 上搭建 OpenTenBase 集群:从源码到生产环境的全流程指南
  • SpringMVC相关自动配置
  • 第四十三天(JavaEE应用ORM框架SQL预编译JDBCMyBatisHibernateMaven)
  • 算法训练营day60 图论⑩ Bellman_ford 队列优化算法、判断负权回路、单源有限最短路
  • Vue 3 useModel vs defineModel:选择正确的双向绑定方案
  • [特殊字符] 在 Windows 新电脑上配置 GitHub SSH 的完整记录(含坑点与解决方案)
  • 简单留插槽的方法
  • 生成一个竖直放置的div,宽度是350px,上面是标题固定高度50px,下面是自适应高度的div,且有滚动条
  • 航空复杂壳体零件深孔检测方法 - 激光频率梳 3D 轮廓检测
  • FFMPEG相关解密,打水印,合并,推流,
  • 鸿蒙中Snapshot分析
  • Vue3+ElementPlus倒计时示例
  • 应用服务器和数据库服务器的区别