英文:
Allow to override/set constraints validation for a child object for Hibernate validation
问题
我有以下的类:
class ContactInformation {
   String phone;
   String email;
}
它被以下的类使用:
class Person {
   @Valid
   ContactInformation contactInformation;
}
class Station {
   @Valid
   ContactInformation contactInformation;
}
问题是,任何 Person 类的实例必须有一个电子邮件地址,但对于 Station 类来说,它是可选信息。我是否有办法在拥有者级别上定义这一点,以避免重复定义 ContactInformation 类?
英文:
I have the following class :
class ContactInformation {
   String phone;
   String email;
}
which is used in the following classes :
class Person {
   @Valid
   ContactInformation contactInformation;
}
class Station {
   @Valid
   ContactInformation contactInformation;
}
The thing is that any instance of Person must have an email, but it is an optional information for Station. Do I have a way to define this at owner level to avoid duplicate the class ContactInformation ?
答案1
得分: 1
代替field级别的验证器,您可以添加Type级别的验证器。
步骤:
- 定义Type级别的注解
 - 编写新注解的验证器
 - 使用新注解引入您的类型
 
定义:
    @Constraint(validatedBy = {PersonClassOptionalEmailValidator.class})
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PersonalEmailValid {
        String message() default "Invalid Email address";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
编写自定义验证器:
    public static class PersonClassOptionalEmailValidator implements ConstraintValidator<PersonalEmailValid, Person> {
        // Test Email validator, you should check proper regex for production
        public static final String EMAIL_REGEX = "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$";
        private final Pattern pattern;
        public PersonClassOptionalEmailValidator() {
            pattern = Pattern.compile(EMAIL_REGEX);
        }
        @Override
        public boolean isValid(Person person, ConstraintValidatorContext constraintValidatorContext) {
            if (person.contactInformation != null) {
                return pattern.matcher(person.contactInformation.email).matches();
            }
            return false;
        }
    }
引入新的注解到类中:
    @Getter
    @Setter
    @NoArgsConstructor
    @PersonalEmailValid
    static class Person {
        @Valid
        ContactInformation contactInformation;
    }
英文:
Instead of the field level validator you can add the Type level validator.
Steps:
- Define Type level annotation
 - Write Validator for new annotation
 - Introduce your type with a new annotation
 
Define:
    @Constraint(validatedBy = {PersonClassOptionalEmailValidator.class})
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PersonalEmailValid {
        String message() default "Invalid Email address";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }
Writing Custom Validator:
    public static class PersonClassOptionalEmailValidator implements ConstraintValidator<PersonalEmailValid, Person> {
        // Test Email validator, you should check prope regex for production
        public static final String EMAIL_REGEX = "^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$";
        private final Pattern pattern;
        public PersonClassOptionalEmailValidator() {
            pattern = Pattern.compile(EMAIL_REGEX);
        }
        @Override
        public boolean isValid(Person person, ConstraintValidatorContext constraintValidatorContext) {
            if (person.contactInformation != null) {
                return pattern.matcher(person.contactInformation.email).matches();
            }
            return false;
        }
    }
Introduce new annotation to class
    @Getter
    @Setter
    @NoArgsConstructor
    @PersonalEmailValid
    static class Person {
        @Valid
        ContactInformation contactInformation;
    }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论