JPA验证电子邮件字符串集合

mcs*_*ral 4 hibernate hibernate-validator bean-validation

我的bean中有一个String列表.这些字符串是电子邮件,我想验证它们.

@Email
@ElementCollection(fetch = FetchType.LAZY)
@OrderColumn
private List<String> emails = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

在执行时,我收到此错误:

Caused by: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.util.List<java.lang.String>.
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.verifyResolveWasUnique(ConstraintValidatorManager.java:218)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.findMatchingValidatorClass(ConstraintValidatorManager.java:193)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:97)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateComposingConstraints(ConstraintTree.java:233)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:102)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:83)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:547)
    ...
Run Code Online (Sandbox Code Playgroud)

这样做的正确方法是什么?或者还有其他方法吗?

Man*_*kus 7

@Email仅适用于StringList,但您可以创建自己的验证器:

@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EmailCollectionValidator.class)
@Documented
public @interface EmailCollection {
    String message() default "Invalid Email";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
Run Code Online (Sandbox Code Playgroud)

验证器:

public class EmailCollectionValidator implements ConstraintValidator<EmailCollection, Collection<String>> {

    @Override
    public void initialize(EmailCollection constraintAnnotation) {

    }

    @Override
    public boolean isValid(Collection<String> value, ConstraintValidatorContext context) {
        if (value == null) {
            return false;
        }
        EmailValidator validator = new EmailValidator();
        for (String s : value) {            
            if (!validator.isValid(s, context)) {
                return false;
            }
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

执行:

@EmailCollection
@ElementCollection(fetch = FetchType.LAZY)
@OrderColumn
private List<String> emails = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)


Har*_*rdy 5

实施额外的约束验证@Email所建议的验证集合在这里是做这件事的一种方式.请注意,如果遇到约束违规,您可能会遇到生成正确属性路径的问题.另见HV-264.

如果您使用的是Java 8,则可以使用最新的Hibernate Validator版本(5.2.x),该版本支持Java 8类型级别注释.你可以写类似的东西List<@Email String>.但是,在这种情况下,您需要立即创建自己的@Email约束注释并确保@Target包含ElementType.TYPE_USE.另请参见Hibernate Validator文档.

下一版本的Bean Validation(2.0)将与Java 8保持一致.所有提供的约束将具有ElementType.TYPE_USE开箱即用的功能.另见BVAL-202.