【问题标题】:JPA Validation of Email String Collection电子邮件字符串集合的 JPA 验证
【发布时间】:2016-01-28 00:41:38
【问题描述】:

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

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

在执行时,我得到了这个错误:

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)
    ...

这样做的正确方法是什么?或者有没有其他方法可以做到这一点?

【问题讨论】:

    标签: hibernate bean-validation hibernate-validator


    【解决方案1】:

    @Email 仅适用于 String 而不是 List,但您可以创建自己的验证器:

    @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 {};
    }
    

    验证者:

    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;
        }
    }
    

    实现:

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

    【讨论】:

    • 只有当集合中的第一个元素有效时,“return validator.isValid(s, context)”行才会返回。我编辑了答案来解决这个问题,但它被拒绝了。
    • 有什么方法可以设置被拒绝的值(仅限无效的电子邮件),以便我只能在 spring 的 fieldError.getRejectedValue() 中获取这些值?
    【解决方案2】:

    按照建议的here@Email 验证集合实施额外的约束验证器是一种方法。请注意,如果您遇到约束违规,您可能无法生成正确的属性路径。另见HV-264

    如果您使用的是 Java 8,您也可以使用支持 Java 8 类型级别注释的最新 Hibernate Validator 版本 (5.2.x)。你可以写List&lt;@Email String&gt;之类的东西。但是,在这种情况下,您现在需要创建自己的@Email 约束注释并确保@Target 包含ElementType.TYPE_USE。另见Hibernate Validator docs

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

    【讨论】:

    • 我尝试使用 List&lt;@Email String&gt;,但它不适用于错误 ava.lang.IllegalStateException: JSR-303 验证属性 'toEmailAddressList[0].' 没有对应的访问器Spring数据绑定但是List&lt;@Email String&gt;工作了
    【解决方案3】:
    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 2011-08-06
    • 2012-07-23
    • 2021-01-13
    • 2016-07-08
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多