Spring中如何使用javax validation实现Java Bean多组合校验
实现方案
要实现多字段组合校验,需要使用javax validation提供的自定义类级别约束,具体步骤如下:
步骤1:调整单字段校验注解
userId、userAltId、userBuyDate、userSellDate是条件必填字段,不需要加全局@NotNull约束;仅保留永久必填字段name、type、gender的非空校验,这里推荐用@NotBlank替代@NotNull,可以同时校验空值、空串、全空白字符串的场景。
步骤2:自定义组合校验注解
创建自定义校验注解,用于标记需要做组合校验的User类:
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) // 声明注解作用在类上 @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = UserValidator.class) // 绑定对应的校验器 public @interface UserValid { // 默认错误提示 String message() default "userId和userAltId至少填写一个,若两者都为空则userBuyDate、userSellDate必须全部填写"; // 分组校验用,默认留空 Class<?>[] groups() default {}; // 负载用,默认留空 Class<? extends Payload>[] payload() default {}; }
步骤3:实现自定义校验器
编写校验逻辑实现类,处理多字段组合规则:
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class UserValidator implements ConstraintValidator<UserValid, User> { @Override public boolean isValid(User user, ConstraintValidatorContext context) { // 校验两个id是否全为空白 boolean userIdIsBlank = user.getUserId() == null || user.getUserId().trim().isEmpty(); boolean altIdIsBlank = user.getUserAltId() == null || user.getUserAltId().trim().isEmpty(); // 场景1:至少有一个id不为空,校验通过 if (!userIdIsBlank || !altIdIsBlank) { return true; } // 场景2:两个id都为空,校验两个日期是否都不为空 return user.getUserBuyDate() != null && user.getUserSellDate() != null; } }
步骤4:修改User类添加自定义注解
import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.validation.constraints.NotBlank; import java.util.Date; @Getter @Setter @ToString @UserValid // 添加自定义组合校验注解 public class User { @NotBlank(message = "Name cannot be null or blank") private String name; @NotBlank(message = "Type cannot be null or blank") private String type; @NotBlank(message = "Gender cannot be null or blank") private String gender; private String userId; private String userAltId; private Date userBuyDate; private Date userSellDate; }
测试验证
原有Test.java代码无需修改,可直接测试不同场景:
- 若name/type/gender任意字段为空白,会返回对应字段的错误提示
- 若userId和userAltId都为空白,且userBuyDate/userSellDate任意一个为空,会返回自定义注解的错误提示
- 其余符合规则的场景校验通过
内容的提问来源于stack exchange,提问作者Mike Marsh
相关产品推荐
相关产品推荐

