【问题标题】:JSR-303 How to validate two children objects differentlyJSR-303 如何以不同方式验证两个子对象
【发布时间】:2013-04-08 22:59:52
【问题描述】:

我使用 Hibernate Validator 作为 JSR-303 实现。

假设我有:

class Form {
    @Valid
    private Owner mainOwner;
    @Valid
    private Owner secondOwner;
    // ... many other fields
}

class Owner {
    @DriverLicenseValid // some custom validation
    private String driverLicense;
    // ... many other fields
}

// ...

Form myForm;
validator.validate(myForm);

看,我想验证整个表单,它包含两个相似的 Owner 类型的子对象。问题是对于 mainOwner driverLicense 应该是 @NotNull 而对于 secondOwner 它应该是 @Null。

我不能在这里使用组(可以吗?),因为整个模型是由单个 validate() 调用检查的。有没有办法在不将此规则编写为表单级别的自定义约束的情况下解决这个问题?

【问题讨论】:

    标签: java bean-validation hibernate-validator


    【解决方案1】:

    Form 中的mainOwner 字段上创建一个验证注释,以验证Owner 实例是否具有设置的驾驶执照。

    @DriverLicenseValid 注释应该遵循 jsr-303 规范中的建议,即 null 值默认有效。所以你不需要更改Owner 类。

    【讨论】:

    • 谢谢,但我在问是否可以在没有表单级别的自定义约束的情况下实现这一点 - 即高于 mainOwner 字段。也许我没有正确表达这一点。但是,由于您提出的解决方案与我自己认为的相同,因此我认为没有其他方法。好的,当然 ScriptAssert 会做,但它几乎与编写自定义验证器相同。
    • @RodionGorkovenko 我想不出任何其他合理的方法来做到这一点。所以你应该坚持你的第一个想法。
    【解决方案2】:

    如果您使用 Hibernate Validator 4.x,则可以使用 forum post 中所述的自定义组序列提供程序。

    【讨论】:

    • 您能否解释一下我如何在这种情况下使用它。如果我注释 Owner 类,那么我将只在 getValidationGroups 方法中获得到 Owner 实例的链接。我无法通过这个实例判断它是由 mainOwner 还是 secondOwner 引用的。如果我注释表单本身 - 我根本无法理解它为验证所有者提供了什么。我很抱歉我的愚蠢。
    • 您必须将状态/角色传递给 Owner 实例,例如像这样:private Owner mainOwner = new Owner("main");。然后,在默认组序列提供程序中,您可以访问角色并返回正确的默认组序列。
    • 啊,谢谢。虽然这绝对不是我想要的。无论如何,感谢您提供有用的信息。
    • 是的,它肯定不完美。请注意,从 Bean Validation 1.1 开始,您将能够使用 group conversions 非常优雅地解决该问题。
    【解决方案3】:

    使用组:

    class Form {
        @Valid
        @ConvertGroup(from=Default.class, to=NotNullDriversLicense.class)
        private Owner mainOwner;
        @Valid
        @ConvertGroup(from=Default.class, to=NullDriversLicense.class)
        private Owner secondOwner;
        // ... many other fields
    }
    
    class Owner {
        @Null(groups = NullDriversLicense.class)
        @NotNull(groups = NotNullDriversLicense.class)
        private String driverLicense;
        // ... many other fields
    }
    
    interface NullDriversLicense {}
    interface NotNullDriversLicense {}
    
    // ...
    
    Form myForm;
    validator.validate(myForm);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-10
      • 2011-05-05
      • 2016-02-25
      • 2011-10-30
      • 2018-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多