news 2026/6/13 0:06:38

拒绝 DTO 爆炸:详解 Spring Boot 参数校验中的“分组校验” (Validation Groups) 技巧

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
拒绝 DTO 爆炸:详解 Spring Boot 参数校验中的“分组校验” (Validation Groups) 技巧

一、 为什么要用分组校验?(痛点)

在日常开发中,我们经常遇到同一个 DTO(数据传输对象)在不同场景下有不同校验规则的情况。

典型场景:用户管理

  • 新增用户ID必须为空(因为是自增的),但Password必填。
  • 修改用户ID不能为空(指定改谁),但Password选填(不改就不传)。

如果没有分组校验,我们通常有两种“笨办法”:

  1. 定义两个 DTOUserCreateReqVOUserUpdateReqVO
    • 缺点:类爆炸,大量重复字段,维护麻烦。
  2. 去掉校验注解:在 DTO 里不写@NotNull,全靠在 Service 层手写if (id == null)判断。
    • 缺点:代码臃肿,失去了注解校验的优雅。

分组校验(Groups)就是为了解决这个问题——用一个 DTO,搞定多种场景。


二、 核心步骤(用法总结)

使用分组校验只需要三步:定义分组 -> 标记规则 -> 触发校验

1. 定义分组接口 (The Marker)

这只是一个普通的 Java 接口,不需要任何方法,它的唯一作用就是做一个“标签”。

publicclassUserReqVO{// 定义两个分组接口publicinterfaceCreate{}publicinterfaceUpdate{}}
2. 在字段上标记分组 (The Rule)

在校验注解中配置groups属性。

@DatapublicclassUserReqVO{@Schema(description="用户ID")@Null(groups=Create.class,message="新增时ID必须为空")@NotNull(groups=Update.class,message="修改时ID不能为空")privateLongid;@Schema(description="用户名")@NotBlank(message="用户名不能为空")// 没有指定 groups,属于默认分组 (Default)privateStringusername;@Schema(description="密码")@NotBlank(groups=Create.class,message="新增时密码不能为空")privateStringpassword;}
3. 触发校验 (The Trigger)

这是最关键的一步。你必须告诉 Spring,当前这次请求,你要检查哪个分组。

注意:必须使用@Validated注解,@Valid不支持分组。

@RestController@RequestMapping("/user")publicclassUserController{// 场景 A:新增 -> 触发 Create 分组@PostMapping("/create")publicResultcreate(@RequestBody@Validated(UserReqVO.Create.class)UserReqVOreq){returnsuccess(userService.create(req));}// 场景 B:修改 -> 触发 Update 分组@PutMapping("/update")publicResultupdate(@RequestBody@Validated(UserReqVO.Update.class)UserReqVOreq){returnsuccess(userService.update(req));}}

三、 进阶:如何处理“默认规则”?(坑点预警)

这里有一个初学者极容易踩的坑。

问题:
在上面的例子中,username字段只加了@NotBlank,没有加groups
当你使用@Validated(Create.class)时,Spring 只会检查标记了Create.class的字段,username会被忽略!

解决方案:让分组接口继承Default

如果你希望在检查Create分组时,也顺便检查那些没有分组的默认字段,可以这样定义接口:

importjavax.validation.groups.Default;publicclassUserReqVO{// 让 Create 分组继承 Default 分组publicinterfaceCreateextendsDefault{}publicinterfaceUpdateextendsDefault{}}

这样,@Validated(Create.class)就会同时检查:

  1. 标记了Create的规则。
  2. 没有标记 group 的规则(归属于Default)。

四、 高阶实战:业务逻辑中的动态校验

除了在 Controller 自动校验,我们有时需要在 Service 层根据业务开关动态校验(例如:验证码开关)。

场景:系统配置了“开启验证码”开关。开启时校验,关闭时不校验。

代码示例:

@ServicepublicclassAuthService{@ResourceprivateValidatorvalidator;// 注入 Java 标准校验器publicvoidlogin(LoginReqVOreq){// 1. 动态判断业务开关if(isCaptchaEnabled()){// 2. 手动触发特定分组 (CodeEnableGroup) 的校验Set<ConstraintViolation<LoginReqVO>>errors=validator.validate(req,CodeEnableGroup.class);// 3. 如果有异常,手动抛出if(!errors.isEmpty()){thrownewServiceException("验证码不能为空");}}// ... 其他逻辑}}

五、 总结

Validation Groups (分组校验)是 Spring Boot 开发中精简代码的神器。

  1. 本质:给校验注解加上“条件判断”。
  2. 核心:通过空接口定义分组 (interface GroupA {})。
  3. 使用:在注解中指定groups = GroupA.class
  4. 触发
    • 自动:Controller 层使用@Validated(GroupA.class)
    • 手动:Service 层使用validator.validate(obj, GroupA.class)
  5. 最佳实践:让自定义分组继承Default接口,避免漏掉通用校验规则。
  6. 缺点:创建与更新复用一个类,高度耦合;需要在Controller中指定class参数;无法实现复杂的方法级别的逻辑校验。有一种平替方案可以见@AssertTrue。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 16:08:40

自定义Bean Validation注解并自定义校验逻辑

自定义校验注解 实现自定义校验注解&#xff0c;本质上是遵循 JSR-303/JSR-380 (Bean Validation) 规范。 在 Spring Boot 中实现它&#xff0c;只需要 两步走&#xff1a; 定义注解&#xff08;接口&#xff09;&#xff1a;相当于制定法律条款。定义校验器&#xff08;实现…

作者头像 李华
网站建设 2026/6/12 0:47:32

深度学习框架实战:TensorFlow与PyTorch的对比与选择指南

摘要随着人工智能技术的快速发展&#xff0c;深度学习框架已成为开发者必备的工具。本文将从实际应用角度出发&#xff0c;深入对比TensorFlow和PyTorch两大主流框架&#xff0c;帮助开发者根据具体需求做出明智选择&#xff0c;并附上实战代码示例。引言在当今AI技术爆炸式发展…

作者头像 李华
网站建设 2026/6/10 19:10:26

【MongoDB实战】7.2 事务实战:转账场景数据一致性保证(完整实操代码)

文章目录 《MongoDB实战入门》7.2 事务实战:转账场景数据一致性保证(完整实操代码) 一、前置说明:MongoDB事务的核心前提 二、核心业务场景定义 三、Node.js版本实战代码(基于mongodb驱动5.x) 1. 安装依赖 2. 完整实操代码 3. 运行结果说明 四、Python版本实战代码(基于…

作者头像 李华
网站建设 2026/6/10 10:43:19

Zookeeper及Kafka

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Zookeeper 1.Zookeeper简介 2.Zookeeper 工作机制 3.Zookeeper 数据结构 4.Zookeeper 应用场景 5.Zookeeper 选举机制 6.部署 Zookeeper 集群 二、Kaf…

作者头像 李华
网站建设 2026/6/10 18:52:15

Altium Designer操作技巧(20)——鼠标滚轮配置详解

大家好,欢迎来到“电子工程师之家”,大家也可以关注微信公众号同号“电子工程师之家”。微信公众号中有更多精彩内容。 家人们,大家好! 今天我们继续分享有关System系统配置中有关鼠标滚轮配置(System - Mouse Wheel Configuration)。 合理配置鼠标滚轮操作,可以提升电…

作者头像 李华
网站建设 2026/6/9 22:53:47

一阶鬼魔魔方

目录 一阶鬼魔魔方 1&#xff0c;魔方三要素 &#xff08;1&#xff09;组成部件 &#xff08;2&#xff09;可执行操作 A套餐&#xff08;用于魔方分类、魔方打乱&#xff09; &#xff08;3&#xff09;可执行操作 B套餐&#xff08;用于魔方复原&#xff09; &#xf…

作者头像 李华