如何在不影响其他及父字段的前提下新增Spring Validation校验规则?
Spring Validation 分组校验规则覆盖方案(不修改原有代码)
问题背景
现有如下Java实体类结构:
@Data public class PojoB { @Size(min = 1, max = 5) @NotBlank() @Pattern(regexp = "[0-9]+") private String code; @Valid private PojoA pojoA; }
@Data public class PojoA { @Size(min = 1, max = 5) @NotBlank() @Pattern(regexp = "[0-9]+") private String code; }
PojoB作为接口/testSpringValidation1的请求体已启用校验,现需新增接口/testSpringValidation2,要求仅放宽pojoA.code的正则校验规则为[0-9a-z]+,其余校验规则与原接口完全一致,且不能修改现有代码。
尝试方案及问题
尝试通过分组校验实现:
- 定义继承
Default的分组接口:
public interface LessValidation extends Default { }
- 新增接口方法:
@PostMapping("/testSpringValidation2") public PojoB testSpringValidation2(@RequestBody @Validated({LessValidation.class}) PojoB reqBody) { return reqBody; }
但调用接口时传入请求体{"code":"12345","pojoA":{"code": "12ab"}},收到错误:
{ "type": "error", "code": "400", "details": "mandatory parameter pojoA.code is invalid: must match \"[0-9]+\"" }
若让LessValidation不继承Default,则PojoB.code等其他字段的校验会被完全跳过,无法满足需求。
解决方案:子类覆盖校验规则
通过创建原有实体类的子类,在子类中重写字段并指定新的校验规则(绑定目标分组),既保留原有所有校验逻辑,又实现局部规则修改:
步骤1:保留原有分组接口
继续使用继承Default的分组接口,确保原有Default分组的校验规则全部生效:
public interface LessValidation extends Default { }
步骤2:创建PojoA的子类,覆盖code字段的正则规则
创建RelaxedPojoA继承PojoA,重写code字段并设置新的Pattern注解,同时指定分组为LessValidation:
@Data public class RelaxedPojoA extends PojoA { // 保留原有Size、NotBlank规则,仅修改Pattern规则并绑定分组 @Size(min = 1, max = 5) @NotBlank() @Pattern(regexp = "[0-9a-z]+", groups = LessValidation.class) private String code; }
步骤3:创建PojoB的子类,替换pojoA的类型
创建RelaxedPojoB继承PojoB,将pojoA的类型改为RelaxedPojoA并保留@Valid注解:
@Data public class RelaxedPojoB extends PojoB { @Valid private RelaxedPojoA pojoA; }
步骤4:修改新接口的请求体类型
将新接口的请求体改为RelaxedPojoB,并使用@Validated({LessValidation.class})触发校验:
@PostMapping("/testSpringValidation2") public RelaxedPojoB testSpringValidation2(@RequestBody @Validated({LessValidation.class}) RelaxedPojoB reqBody) { return reqBody; }
原理说明
- 原有实体类的校验注解默认属于
Default分组,LessValidation继承Default后,校验时会执行所有Default分组的规则; RelaxedPojoA中Pattern注解指定了LessValidation分组,校验时会优先使用该分组下的规则,覆盖原有Default分组的Pattern规则;- 其他未修改的字段(如
PojoB.code)仍沿用原有Default分组的校验规则,确保整体校验逻辑与原接口一致。
内容的提问来源于stack exchange,提问作者ildvzg68472
相关产品推荐
相关产品推荐

