【问题标题】:Spring custom condition based validation基于 Spring 自定义条件的验证
【发布时间】:2018-06-01 05:37:17
【问题描述】:

我想在 spring 验证器中创建基于条件的验证。 我有一个 UserDTO 类,其中有两个带有 @Valid 注释的 DTO 类。

如果我通过 isPrimary true 那么它应该只验证 primaryDTO bean 并忽略 secendoryDTO 验证。

public class UserDTO {
    @Valid
    private PrimaryDTO primaryDTO;
    @Valid
    private SecendoryDTO secendoryDTO;
    private boolean isPrimary;
}

public class PrimaryDTO {
    @NotEmpty(message = "Please enter email.")
    @Email(message = "Please enter a valid email.")
    private String email;
}

public class SecendoryDTO {
    @NotEmpty(message = "Please enter phone.")
    private String phone;
}

请指导。

谢谢

【问题讨论】:

    标签: java spring spring-mvc spring-boot spring-validator


    【解决方案1】:

    如果您的验证依赖于多个字段(例如 isPrimaryprimaryDTOsecondaryDTO),那么唯一的解决方案是在类级别 (UserDTO) 上编写一个自定义验证器,它将实现条件验证自己。

    例如,创建一个注解:

    @Documented
    @Retention(RUNTIME)
    @Target({ANNOTATION_TYPE, TYPE})
    @Constraint(validatedBy = SecondaryValidator.class)
    public @interface ValidSecondary {
        String message() default "Invalid secondary";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
    

    并创建一个仅在isPrimary()false 时验证secondaryDTO 字段的验证器:

    @Component
    public class SecondaryValidator implements ConstraintValidator<ValidSecondary, UserDTO> {
        private Validator validator;
    
        public SecondaryValidator(Validator validator) {
            this.validator = validator;
        }
    
        @Override
        public boolean isValid(UserDTO userDTO, ConstraintValidatorContext constraintValidatorContext) {
            if (userDTO.isPrimary()) {
                return true;
            } else {
                return validator.validate(userDTO.getSecondaryDTO()).isEmpty();
            }
        }
    }
    

    之后,您可以从secondaryDTO 字段中删除@Valid 注释,并在UserDTO 顶部添加@ValidSecondary 注释:

    @ValidSecondary // Add this
    public class UserDTO {
        @Valid
        private PrimaryDTO primaryDTO;
        private SecondaryDTO secondaryDTO; // No more @Valid
        private boolean primary;
    }
    

    但是,在这种情况下,您将丢失来自 SecondaryDTO 内的任何约束违规消息,如果您想要某种传递机制,您可以将违规添加到 isValid() 内的 constraintValidatorContext方法,例如:

    Set<ConstraintViolation<SecondaryDTO>> violations = validator.validate(userDTO.getSecondaryDTO());
    violations.forEach(violation -> constraintValidatorContext
        .buildConstraintViolationWithTemplate(violation.getMessage())
        .addConstraintViolation());
    

    【讨论】:

    • 我收到一个错误原因:java.lang.NoSuchMethodException : SecondaryValidator.() 在此类 SecondaryValidator
    • @ParthSolanki 你应该在构造函数中添加@Autowired
    猜你喜欢
    • 2021-07-10
    • 1970-01-01
    • 2019-10-14
    • 2016-06-09
    • 2022-01-23
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多