2026/1/11 5:09:02
网站建设
项目流程
贵州省住房和城乡建设厅网站,在线观看永久免费网站网址,建筑工程服务有限公司,app软件开发怎么写一、 为什么要用分组校验#xff1f;#xff08;痛点#xff09;
在日常开发中#xff0c;我们经常遇到同一个 DTO#xff08;数据传输对象#xff09;在不同场景下有不同校验规则的情况。
典型场景#xff1a;用户管理
新增用户#xff1a;ID 必须为空#xff08;因为…一、 为什么要用分组校验痛点在日常开发中我们经常遇到同一个 DTO数据传输对象在不同场景下有不同校验规则的情况。典型场景用户管理新增用户ID必须为空因为是自增的但Password必填。修改用户ID不能为空指定改谁但Password选填不改就不传。如果没有分组校验我们通常有两种“笨办法”定义两个 DTOUserCreateReqVO和UserUpdateReqVO。缺点类爆炸大量重复字段维护麻烦。去掉校验注解在 DTO 里不写NotNull全靠在 Service 层手写if (id null)判断。缺点代码臃肿失去了注解校验的优雅。分组校验Groups就是为了解决这个问题——用一个 DTO搞定多种场景。二、 核心步骤用法总结使用分组校验只需要三步定义分组 - 标记规则 - 触发校验。1. 定义分组接口 (The Marker)这只是一个普通的 Java 接口不需要任何方法它的唯一作用就是做一个“标签”。publicclassUserReqVO{// 定义两个分组接口publicinterfaceCreate{}publicinterfaceUpdate{}}2. 在字段上标记分组 (The Rule)在校验注解中配置groups属性。DatapublicclassUserReqVO{Schema(description用户ID)Null(groupsCreate.class,message新增时ID必须为空)NotNull(groupsUpdate.class,message修改时ID不能为空)privateLongid;Schema(description用户名)NotBlank(message用户名不能为空)// 没有指定 groups属于默认分组 (Default)privateStringusername;Schema(description密码)NotBlank(groupsCreate.class,message新增时密码不能为空)privateStringpassword;}3. 触发校验 (The Trigger)这是最关键的一步。你必须告诉 Spring当前这次请求你要检查哪个分组。注意必须使用Validated注解Valid不支持分组。RestControllerRequestMapping(/user)publicclassUserController{// 场景 A新增 - 触发 Create 分组PostMapping(/create)publicResultcreate(RequestBodyValidated(UserReqVO.Create.class)UserReqVOreq){returnsuccess(userService.create(req));}// 场景 B修改 - 触发 Update 分组PutMapping(/update)publicResultupdate(RequestBodyValidated(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)就会同时检查标记了Create的规则。没有标记 group 的规则归属于Default。四、 高阶实战业务逻辑中的动态校验除了在 Controller 自动校验我们有时需要在 Service 层根据业务开关动态校验例如验证码开关。场景系统配置了“开启验证码”开关。开启时校验关闭时不校验。代码示例ServicepublicclassAuthService{ResourceprivateValidatorvalidator;// 注入 Java 标准校验器publicvoidlogin(LoginReqVOreq){// 1. 动态判断业务开关if(isCaptchaEnabled()){// 2. 手动触发特定分组 (CodeEnableGroup) 的校验SetConstraintViolationLoginReqVOerrorsvalidator.validate(req,CodeEnableGroup.class);// 3. 如果有异常手动抛出if(!errors.isEmpty()){thrownewServiceException(验证码不能为空);}}// ... 其他逻辑}}五、 总结Validation Groups (分组校验)是 Spring Boot 开发中精简代码的神器。本质给校验注解加上“条件判断”。核心通过空接口定义分组 (interface GroupA {})。使用在注解中指定groups GroupA.class。触发自动Controller 层使用Validated(GroupA.class)。手动Service 层使用validator.validate(obj, GroupA.class)。最佳实践让自定义分组继承Default接口避免漏掉通用校验规则。缺点创建与更新复用一个类高度耦合需要在Controller中指定class参数无法实现复杂的方法级别的逻辑校验。有一种平替方案可以见AssertTrue。