繁体   English   中英

休眠验证器中的 TYPE_USE 注释

[英]TYPE_USE annotation in hibernate validator

我知道 hibernate 验证器支持TYPE_USE注释:虽然它没有定义自己的注释,但它允许您定义和使用自定义注释。

我可以正确定义和验证这样的注释(很快代码),但是我想将错误映射到用于向用户显示错误的路径中。

给出以下示例

public class SampleTest {

    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    public static class LimitedSizeStringValidator implements ConstraintValidator<LimitedSize, String> {

        private LimitedSize constraint;

        @Override
        public void initialize(LimitedSize constraintAnnotation) {
            this.constraint = constraintAnnotation;
        }

        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
            String s = Ensure.notNull(value);
            return s.length() >= constraint.min() &&
                s.length() <= constraint.max();
        }
    }

    @Retention(RUNTIME)
    @Documented
    @Target({TYPE_USE})
    @Constraint(validatedBy = {LimitedSizeStringValidator.class})
    public @interface LimitedSize {

        String message() default "{javax.validation.constraints.Size.message}";

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

        Class<? extends Payload>[] payload() default {};

        int min() default 0;

        int max() default Integer.MAX_VALUE;
    }

    private static class TestBean {
        @Valid
        private Collection<@LimitedSize(max = 3) String> strings = new ArrayList<>();

        @Valid
        private Collection<InnerBean> beans = new ArrayList<>();
    }

    private static class InnerBean {
        @Min(3)
        private final int value;

        private InnerBean(int value) {
            this.value = value;
        }
    }

    @Test
    public void testBeanInvalid() {

        TestBean testBean = new TestBean();

        assertThat(validator.validate(testBean)).isEmpty();

        testBean.strings.add("ok");
        testBean.strings.add("ok2");
        testBean.beans.add(new InnerBean(4));
        assertThat(validator.validate(testBean)).isEmpty();

        testBean.strings.add("not_ok");
        testBean.beans.add(new InnerBean(2));

        Set<ConstraintViolation<TestBean>> violations = validator.validate(testBean);
        assertThat(violations).hasSize(2);

        StreamSupport.stream(violations.spliterator(), false)
            .forEach(v -> {
                System.out.println(v.getPropertyPath());
                System.out.println(v.getMessage());
                v.getPropertyPath().forEach(p -> System.out.print("'" + p.getName() + (p.getIndex() != null ? "[" + p.getIndex() + "]" : "") + "' -> "));
                System.out.println();
            });
    }
}

我想映射一个对象中的错误,比如

errors: [
  ["beans", "1", "value"],
  ["strings", "2"]
]

与我的示例一样,我目前的方法是导航违规路径( http://docs.oracle.com/javaee/7/api/javax/validation/ConstraintViolation.html#getPropertyPath-- ),这对于第一种情况,但第二种情况失败(我找不到检索失败对象索引的方法)。 我认为原因在于 hibernate-validator 中javax.validation.Path.PropertyNode的实现(我目前在5.2.4.Final版本5.2.4.Final ,代码看起来与链接的5.2.1.Final的相同。供参考:

@Override
public final Integer getIndex() {
    if ( parent == null ) {
        return null;
    }
    else {
        return parent.index;
    }
}

使用TYPE_USE这种方法在我看来是行不通的,因为失败的对象是叶子,因此没有子节点可以从中检索索引。

很不错, javax.validation.Path休眠实现覆盖了toString方法,这样的方法javax.validation.Path violation.getPropertyPath().toString()beans[1].valuestrings[2] (在上面的示例代码中)。

所以,对于问题:我的导航方法是错误的,还有另一种方法可以从ConstraintViolation提取这样的映射吗? 或者这是对休眠开发人员的功能请求(我可以看到在TYPE_USE注释getIndex他们实现的getIndex方法完全没问题?

只是感觉很奇怪我是第一个遇到这个问题的人(我试图用谷歌搜索并找不到任何相关的东西,最接近的是: https : //github.com/hibernate/hibernate-validator/pull/441 )所以我想知道错误是否是我的而不是休眠限制

我同意应该为该值设置索引,并认为您在 Hibernate Validator 中发现了一个问题。 你能在我们的JIRA 跟踪器中打开一个问题吗?

顺便提一句。 TYPE_USE 级别约束的概念将从 Bean Validation 2.0 开始标准化。 所以这个领域可能会有更多的变化,特别是我想知道那个节点应该有什么Kind (目前它是PROPERTY似乎有问题)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM