继承类的 Spring MVC 验证

Posted

技术标签:

【中文标题】继承类的 Spring MVC 验证【英文标题】:Spring MVC Validation of Inherited Classes 【发布时间】:2014-03-17 11:08:58 【问题描述】:

我很难相信我是唯一一个想要这样做的人,但我找不到任何参考资料来帮助我克服障碍。使用 Spring MVC 和基于注解的验证(我使用的是框架 4.0 和 Java 1.7),考虑一个简单的类层次结构,如下所示:

abstract class Foo 

    @Size(max=10, message = "The name has to be 10 characters or less.")
    private String name;

    public String getName() 
        return this.name;
    

    public void setName(String name) 
        this.name = name;
    


class Bar extends Foo 



class Bang extends Foo 


如果我将 name 放在大于 10 个字符的 Bar 或 Bang 的实例中,我会收到预期的验证错误。不过,假设我仍然希望 Bar 和 Bang 从抽象基类 Foo 派生,但我希望子类的 name 属性具有不同的验证。

如何注释 Bar 和 Bang,以便 Bar.name 的最大长度为 12 个字符,而 Bang.name 的最大长度为 8 个字符?

非常感谢, 抢

【问题讨论】:

a similar one 我看到了。我在覆盖的 getter 方法上尝试了“累积”的东西,而在基类上没有验证。发生的事情是验证根本没有发生。我已经尝试在各个地方使用@Valid,但我仍然无法让验证器在被覆盖的 getter 上触发。我是否必须在基类上设置一个“@Size”验证器,然后在扩展类上进一步限制它?像基类上的 max=1000 和扩展上的 max=12 一样利用注释验证的“累积”性质? 重点是,由于这种累积性质,JSR303 注释无法覆盖。 我想我必须接受这个答案,即使我不喜欢它。 :-/ 谢谢,@gadget。 【参考方案1】:

简短的回答是,在 Bean Validation 中无法禁用超类中的约束。这里有一个功能请求https://hibernate.atlassian.net/browse/BVAL-256 建议引入@OverrideConstraint 或@IgnoreInheritedConstraint 类型的注释。不过,目前还无法做到这一点。

另请参阅 http://lists.jboss.org/pipermail/beanvalidation-dev/2012-January/000128.html 和 https://hibernate.atlassian.net/browse/HV-548。

【讨论】:

【参考方案2】:

在派生类中创建一个新字段并覆盖方法。

class Bar extends Foo 
    @Size(max=12, message = "The name has to be 12 characters or less.")
    private String name;

    @Override
    public String getName() 
        return this.name;
    

    @Override
    public void setName(String name) 
        this.name = name;
    

【讨论】:

谢谢,但这样不是违背了拥有抽象基类的目的吗? 如果您只使用抽象类来保存name 字段,是的。如果抽象类包含其他常见的字段、方法等,它可能是值得的。 我明白你的意思。远离我过于简化的“Foo Bar Bang”示例,它基本上是一个抽象的 Person 类,包含更多特定类型的人可以扩展的所有常见属性。【参考方案3】:

你也可以在getter方法上加上@Size(max=12, message = "The name has to be 12 characters or less.")注解。

所以只需覆盖名称字段并将您的个性化注释放在 getter 方法上。 它将与将验证注释放在字段上相同。请参阅下面的示例:

class Bar extends Foo 

    @Override 
    @Size(max=12, message = "The name has to be 12 characters or less.")
    public void getName(String name)
        
            this.name = name;
        

【讨论】:

这个解决方案似乎不正确!首先, Bar 没有 name 字段,因为它在超类中是私有的。其次,Getter 方法不是 Setter 方法!! 它是 setter,而不是 getter,getter 序列化,setter 在反序列化期间验证工作。

以上是关于继承类的 Spring MVC 验证的主要内容,如果未能解决你的问题,请参考以下文章

带有注释的 Spring MVC 验证

使用全注解配置Spring MVC

Spring 3 MVC:使用自定义验证器显示验证消息

spring-mvc中抽象类的数据绑定

Spring MVC REST + Spring Security + 基本身份验证

扯谈spring mvc之WebApplicationContext的继承关系