Spring Boot REST接口Bean校验新增/更新场景代码重复怎么解决?
解决方案:使用Bean Validation分组校验能力
这是Spring Boot生态下适配同个实体多套校验规则的原生标准方案,无需拆分重复的模型类,也无需额外抽离校验逻辑,完全符合你的需求。
实现步骤
1. 定义分组标记接口
仅需定义两个空接口,作为不同场景的校验分组标记,不需要写任何实现逻辑:
// 新增客户场景校验分组 public interface CreateGroup {} // 更新客户场景校验分组 public interface UpdateGroup {}
2. 给实体类校验注解指定所属分组
在你的Customer、CustomerAddress模型类的校验注解上,新增groups属性指定该规则生效的场景:
import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; @Data public class Customer { // 新增、更新场景都要求名字非空,所以同时指定两个分组 @NotBlank(message = "客户名不能为空", groups = {CreateGroup.class, UpdateGroup.class}) private String customerFirstName; @NotBlank(message = "客户姓氏不能为空", groups = {CreateGroup.class, UpdateGroup.class}) private String customerLastName; // 仅新增场景要求地址必填,更新场景不限制,所以只指定CreateGroup @NotNull(message = "客户地址不能为空", groups = CreateGroup.class) @Valid // 嵌套校验必须加,地址内部字段的分组规则才会生效 private CustomerAddress customerAddress; } @Data public class CustomerAddress { // 可以灵活配置内部字段的生效分组,比如仅新增时要求地址行1必填 @NotBlank(message = "地址行1不能为空", groups = CreateGroup.class) private String addressLine1; private String addressLine2; private String state; private String country; private String zipCode; }
3. Controller接口指定对应校验分组
用Spring提供的@Validated注解替换原有@Valid,指定该接口要触发的校验分组即可:
import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/customer") public class CustomerController { // 新增接口触发CreateGroup分组校验 @PostMapping public void addCustomer(@RequestBody @Validated(CreateGroup.class) Customer customer) { // 新增业务逻辑 } // 更新接口触发UpdateGroup分组校验 @PutMapping("/{customerId}") public void updateCustomer(@PathVariable Long customerId, @RequestBody @Validated(UpdateGroup.class) Customer customer) { // 更新业务逻辑,仅修改传入的字段即可 } }
关于校验逻辑抽离的合理性说明
如果你的校验规则仅为字段非空、格式校验这类单字段规则,不需要使用抽离校验的方案,原生分组校验已经足够简洁、易维护。
只有当你需要实现复杂的多字段关联校验、或者校验逻辑需要依赖外部数据源(比如校验客户ID是否存在)这类场景时,才建议抽离独立的校验器实现。
内容的提问来源于stack exchange,提问作者kumartj
相关产品推荐
相关产品推荐

