简体   繁体   English

休眠验证器中的 TYPE_USE 注释

[英]TYPE_USE annotation in hibernate validator

I know hibernate validator supports TYPE_USE annotations: though it does not define its own, it lets you define and use custom ones.我知道 hibernate 验证器支持TYPE_USE注释:虽然它没有定义自己的注释,但它允许您定义和使用自定义注释。

I could define and validate correctly such an annotation (code soon), but then I want to map the error into a path that is used to display the error to the user.我可以正确定义和验证这样的注释(很快代码),但是我想将错误映射到用于向用户显示错误的路径中。

Given then following sample给出以下示例

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

I would like map the errors in an object like我想映射一个对象中的错误,比如

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

As in my sample, my approach at the moment is by navigating the violation path ( http://docs.oracle.com/javaee/7/api/javax/validation/ConstraintViolation.html#getPropertyPath-- ) which works perfectly for the first case, but fails for the second (I cannot find a way to retrieve the index of the failing object).与我的示例一样,我目前的方法是导航违规路径( http://docs.oracle.com/javaee/7/api/javax/validation/ConstraintViolation.html#getPropertyPath-- ),这对于第一种情况,但第二种情况失败(我找不到检索失败对象索引的方法)。 I think the reason is in the implementation of javax.validation.Path.PropertyNode in hibernate-validator (I am currently on version 5.2.4.Final , and the code looks the same as in the linked 5.2.1.Final . For reference:我认为原因在于 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;
    }
}

With TYPE_USE this approach cannot work in my opinion, because the failing object is a leaf, thus no child node can retrieve the index from it.使用TYPE_USE这种方法在我看来是行不通的,因为失败的对象是叶子,因此没有子节点可以从中检索索引。

Nice enough, hibernate implementation of javax.validation.Path overrides the toString method is way such that violation.getPropertyPath().toString() is beans[1].value and strings[2] (in the sample code above).很不错, javax.validation.Path休眠实现覆盖了toString方法,这样的方法javax.validation.Path violation.getPropertyPath().toString()beans[1].valuestrings[2] (在上面的示例代码中)。

So, to the question(s): is my navigation approach wrong and there is another way to extract such a mapping from the ConstraintViolation ?所以,对于问题:我的导航方法是错误的,还有另一种方法可以从ConstraintViolation提取这样的映射吗? Or is this a feature request for hibernate developers (I can see that before TYPE_USE annotations the getIndex approach they implemented was totally fine?或者这是对休眠开发人员的功能请求(我可以看到在TYPE_USE注释getIndex他们实现的getIndex方法完全没问题?

It just feels strange I am the first one with this problem (I tried to google and could not find anything related, the closest being: https://github.com/hibernate/hibernate-validator/pull/441 ) so I am wondering whether the mistake is mine rather than a hibernate limitation只是感觉很奇怪我是第一个遇到这个问题的人(我试图用谷歌搜索并找不到任何相关的东西,最接近的是: https : //github.com/hibernate/hibernate-validator/pull/441 )所以我想知道错误是否是我的而不是休眠限制

I agree that the index should be set for that value and think you uncovered an issue in Hibernate Validator.我同意应该为该值设置索引,并认为您在 Hibernate Validator 中发现了一个问题。 Could you open an issue in our JIRA tracker ?你能在我们的JIRA 跟踪器中打开一个问题吗?

Btw.顺便提一句。 the notion of TYPE_USE level constraints will be standardized as of Bean Validation 2.0. TYPE_USE 级别约束的概念将从 Bean Validation 2.0 开始标准化。 So there may be some more changes coming up in this area, specifically I'm wondering what Kind that node should have (currently it's PROPERTY which seems questionable).所以这个领域可能会有更多的变化,特别是我想知道那个节点应该有什么Kind (目前它是PROPERTY似乎有问题)。

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

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