Bean Validation:结合校验组与组序列实现指定规则校验
如何通过校验组实现指定顺序与场景的实体校验需求
需求说明
我有一个配置了校验规则的User实体类,需要实现以下校验逻辑:
- email字段:
@NotBlank校验优先执行@Email校验紧随其后@UniqueEmail仅在创建用户时执行,且排在第三位
- password字段:
@NotBlank与@Length(min=8)校验优先执行
现有代码
实体类User
@Entity public class User{ @NotBlank // 需优先执行 @Email(regexp = "xxxxx") // 需第二位执行 @UniqueEmail // 仅创建时执行,且第三位 private String email; @NotBlank // 需优先执行 @Length(min = 8) // 需优先执行 private String password; }
服务类UserService
@Service public class UserService { public void addUser(@Validated(OnCreate.class) User user){...} public void updateUser(User user){...} }
校验组类UserValidationGroups
public class UserValidationGroups { @GroupSequence({Default.class, EmailFormatValid.class, UniqueEmail.class}) public interface UserValidationGroupSeqence{} public interface UniqueEmail{} public interface EmailFormatValid{} }
解决方案
要实现需求,需要明确校验注解的分组归属,并通过@GroupSequence控制执行顺序,同时绑定场景分组(创建用户):
1. 调整校验组定义
补充OnCreate场景分组,并让它关联顺序组,确保创建时按指定顺序执行所有校验:
public class UserValidationGroups { // 定义校验顺序:先执行Default组,再邮箱格式校验,最后唯一邮箱校验 @GroupSequence({Default.class, EmailFormatValid.class, UniqueEmail.class}) public interface CreateUserSequence {} // 创建用户场景分组,绑定顺序规则 public interface OnCreate extends CreateUserSequence {} // 邮箱格式校验专属分组 public interface EmailFormatValid {} // 唯一邮箱校验专属分组 public interface UniqueEmail {} }
2. 修改实体类的校验注解
为每个校验规则指定对应的分组,明确执行顺序的归属:
@Entity public class User{ // @NotBlank属于默认组(Default),优先执行 @NotBlank // @Email指定到EmailFormatValid组,第二位执行 @Email(regexp = "xxxxx", groups = UserValidationGroups.EmailFormatValid.class) // @UniqueEmail指定到UniqueEmail组,仅创建时触发且第三位执行 @UniqueEmail(groups = UserValidationGroups.UniqueEmail.class) private String email; // 两个注解都属于默认组,会在第一阶段优先执行 @NotBlank @Length(min = 8) private String password; }
注意:自定义注解
@UniqueEmail需要支持groups属性,确保它能接收分组参数(如果是Spring自定义校验注解,需在注解定义中添加groups()属性)。
3. 调整服务类的校验注解
- 创建用户时使用
OnCreate分组,触发完整顺序校验 - 更新用户时使用默认
@Validated,跳过UniqueEmail校验:
@Service public class UserService { // 创建用户:触发OnCreate分组,按顺序执行所有校验 public void addUser(@Validated(UserValidationGroups.OnCreate.class) User user){...} // 更新用户:仅执行Default组校验(跳过UniqueEmail) public void updateUser(@Validated User user){...} }
逻辑说明
- 顺序控制:通过
CreateUserSequence的@GroupSequence定义,确保校验按Default→EmailFormatValid→UniqueEmail的顺序执行,只有前一组校验通过才会执行下一组。 - 场景控制:
OnCreate分组绑定了顺序规则,所以创建用户时会触发所有分组的校验;更新用户时仅使用默认组,不会触发UniqueEmail所在的分组。 - password字段:两个注解都属于
Default组,会在第一阶段优先执行,同一组内的校验并行执行(符合需求中"优先执行"的要求)。
内容的提问来源于stack exchange,提问作者PoCiTo
相关产品推荐
相关产品推荐

