【问题标题】:can I override a jsr-303 validation annotation我可以覆盖 jsr-303 验证注释吗
【发布时间】:2012-02-22 10:57:30
【问题描述】:

我有如下测试:

public class TestSizeAnnotation
{
    public static void main(String[] args)
    {
        System.out.println(Validation.buildDefaultValidatorFactory().getValidator().validate(new C()));
    }

    public static class P
    {
        private List<String> lst = newArrayList("AA");
        @Size(max=0, message="P")
        public List<String> getLst()
        {
            return lst;
        }

        public void setLst(List<String> lst)
        {
            this.lst = lst;
        }
    }

    public static class C extends P
    {
        @Override
        @Size(max=5, message="C")
        public List<String> getLst()
        {
            return super.getLst();
        }
    }
}

输出如下:
[ConstraintViolationImpl{interpolatedMessage='P', propertyPath=lst, rootBeanClass=class com....validator.TestSizeAnnotation$C, messageTemplate='P'}]

但是,我希望注释可以@Size 被覆盖,并且不会出现警告。
有没有办法做到这一点?

编辑:我发现 bug 似乎与此有关,但我运行 4.2.0 final 并仍然得到上述行为。

【问题讨论】:

    标签: java hibernate annotations bean-validation


    【解决方案1】:

    JSR-303 实际上不支持覆盖验证注释。相反,子类中重写方法的注释将累积应用:来自规范的第 3.3 节:

    约束声明可以放在接口上。对于给定的类, 超类和接口上的约束声明是 由 Bean Validation 提供程序评估。规则正式描述在 第 3.4.5 节。 约束声明的效果是累积的。 声明的约束 在超类 getter 上将与定义的任何约束一起进行验证 根据 Java 语言,在 getter 的覆盖版本上 规范可见性规则。

    【讨论】:

    • 所以这意味着我不能在超类中覆盖@NotNull,对吧?谢谢。
    【解决方案2】:

    您可以通过 xml 配置来覆盖注解配置的验证:

    http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html_single/#validator-xmlconfiguration

    在您的情况下,如果您在validation.xml 文件中为getList() 方法声明不同的验证(或不验证),它将覆盖@Size 注释。

    【讨论】:

    • 不,我想使用默认验证器,但覆盖注释。
    • 正如 Perception 在他的回答中所说,不,您实际上不能在代码中覆盖它们。
    【解决方案3】:

    为了记录,我找到了解决我的问题的方法:

    public class TestSizeAnnotation
    {
        public static void main(String[] args)
        {
            System.out.println("c " + 
                    Validation.buildDefaultValidatorFactory().getValidator().validate(new C(), Default.class, SizeGroup2.class));
            System.out.println("p " + 
                    Validation.buildDefaultValidatorFactory().getValidator().validate(new P(), Default.class, SizeGroup.class));
        }
        public static interface SizeGroup {}
        public static interface SizeGroup2 {}
        public static class P 
        {
            private List<String> lst = newArrayList("AA");
            @Size(max=0, message="P" , groups=SizeGroup.class)
            public List<String> getLst()
            {
                return lst;
            }
            public void setLst(List<String> lst)
            {
                this.lst = lst;
            }
        }
        public static class C extends P 
        {
            @Override
            @Size(max=5, message="C", groups=SizeGroup2.class)
            public List<String> getLst()
            {
                return super.getLst();
            }
    
        }
    }
    

    【讨论】:

    • 这不是覆盖,而是累积。在这种情况下,如果第二次验证通过,初始验证将始终通过,但在其他情况下,例如初始验证为 Min(...) 然后将 Max(...) 添加到覆盖方法中,您让它同时使用 Min 和 Max 验证(Max 不会覆盖初始 Min)。
    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2015-01-10
    • 2011-09-12
    • 1970-01-01
    • 2018-08-15
    相关资源
    最近更新 更多