如何按顺序校验Spring DTO的多个验证注解,优先执行@NotBlank再校验@Pattern
实现方案
核心是通过 分组校验+校验序列 控制注解的执行顺序,前序校验失败直接终止后续校验,步骤如下:
步骤1:定义两个标记分组接口
// 第一优先级校验分组(用于@NotBlank) public interface FirstGroup { } // 第二优先级校验分组(用于@Pattern) public interface SecondGroup { }
步骤2:修改DTO类,给注解分配分组并指定校验顺序
给字段的注解指定对应分组,同时在类上添加@GroupSequence注解定义校验顺序:
@Getter @Setter // 按顺序校验:先执行FirstGroup,所有校验通过才执行SecondGroup,前序分组失败直接终止 @GroupSequence({FirstGroup.class, SecondGroup.class, DeviceData.class}) public class DeviceData implements Serializable { @NotBlank(message = "device id required", groups = FirstGroup.class) private String deviceId; @NotBlank(message = "client trans id required", groups = FirstGroup.class) @Pattern(regexp = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" , message = "client trans id format error", groups = SecondGroup.class) private String clientTransId; @NotBlank(message = "device info required", groups = FirstGroup.class) private String deviceInfo; }
注意:@GroupSequence中必须加入当前DTO类本身,否则会违反JSR-380校验规范。
步骤3:Controller层指定校验分组
接口参数的@Validated注解直接指定DTO类即可,会自动按定义的序列顺序校验:
@PostMapping("/device/data") public Object receiveData(@RequestBody @Validated(DeviceData.class) DeviceData data) { // 业务逻辑 return null; }
原理说明
Spring Validation默认会执行字段上所有匹配分组的校验注解,不会按注解书写顺序执行。通过@GroupSequence指定分组顺序后,只要前序分组存在校验失败的情况,就会直接终止后续分组的校验,完全符合你要求的@NotBlank校验不通过就不执行@Pattern的需求。
内容的提问来源于stack exchange,提问作者Geeth
相关产品推荐
相关产品推荐

