Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 委托(通用)约束定义注释_Java_Validation_Bean Validation - Fatal编程技术网

Java 委托(通用)约束定义注释

Java 委托(通用)约束定义注释,java,validation,bean-validation,Java,Validation,Bean Validation,在JSR-303(Bean验证)中,您需要为您编写的每个约束验证器定义一个特殊的注释。如果您正在创建可重用的约束验证器(如标准的@Max,@NotNull等),那么这非常有意义 然而,在现实生活中,每个经过验证的bean都需要自己的验证器来执行更复杂的业务验证。对于普通的JSR-303实现,您必须为每个验证器创建单独的注释。这迫使开发人员只编写一次注释,使bean验证的总体概念看起来很愚蠢。如果JSR-303提供某种委托约束注释,则可以避免一次性注释的必要性:@ValidateBy(valida

在JSR-303(Bean验证)中,您需要为您编写的每个约束验证器定义一个特殊的注释。如果您正在创建可重用的约束验证器(如标准的
@Max
@NotNull
等),那么这非常有意义

然而,在现实生活中,每个经过验证的bean都需要自己的验证器来执行更复杂的业务验证。对于普通的JSR-303实现,您必须为每个验证器创建单独的注释。这迫使开发人员只编写一次注释,使bean验证的总体概念看起来很愚蠢。如果JSR-303提供某种委托约束注释,则可以避免一次性注释的必要性:
@ValidateBy(validator=my.custom.validator)

现在我的问题是:

  • 为什么JSR-303不包含这样的用例
  • 是否有任何与此相关的官方讨论(我找不到任何东西)
  • 有JSR-303库提供这样的功能吗(并不是说实现起来很难)

更新1特定用例(导致此问题)

我们有一个中等规模的企业应用程序,具有非常丰富的业务模型(40个可管理实体、20个可嵌入实体、25个只读实体)。这意味着我们有很多HTML表单。每个表单都有一个带有JSR-303注释的指定表单bean(70个表单bean)支持。某些表单需要自定义非平凡验证(例如,如果传递类型为电子邮件,则必须设置联系人电子邮件…)。使用JSR-303,我们有33个特定于表单bean的验证器,带有33个(不必要的一次性)注释


由于Java类(实体、控制器、DAO、DTO、映射器、验证器等)的数量太多,现在有800个
.Java
文件,我不喜欢有任何样板代码。

Bean验证的核心原则之一是类型安全。特定约束注释(如
@Max
@Size
)允许以类型安全的方式指定和访问自定义属性(如允许的最大值)

所选择的方法还允许验证引擎根据注释元素的类型选择正确的验证器实现,而不需要用户指定验证器类。因此,在某种程度上,这将复杂性从约束用户转移到了约束作者

正如您所说,将其作为自定义约束实现应该并不困难。请注意,这会禁用编译时对约束正确性的检查,例如通过Hibernate Validator提供的。虽然这可以检测到字符串属性上错误指定的
@pass
约束,但无法检测通过
@ValidatedBy
指定的不匹配验证程序类型

如果您的要求是关于完整bean的自定义验证逻辑(类级别验证),那么您可以考虑在bean的方法中实现如下:

@AssertTrue
public boolean isValid() {
    //custom validation logic
}

或者您可以利用Hibernate Validator提供的约束。

Bean验证的核心原则之一是类型安全。特定约束注释(如
@Max
@Size
)允许以类型安全的方式指定和访问自定义属性(如允许的最大值)

所选择的方法还允许验证引擎根据注释元素的类型选择正确的验证器实现,而不需要用户指定验证器类。因此,在某种程度上,这将复杂性从约束用户转移到了约束作者

正如您所说,将其作为自定义约束实现应该并不困难。请注意,这会禁用编译时对约束正确性的检查,例如通过Hibernate Validator提供的。虽然这可以检测到字符串属性上错误指定的
@pass
约束,但无法检测通过
@ValidatedBy
指定的不匹配验证程序类型

如果您的要求是关于完整bean的自定义验证逻辑(类级别验证),那么您可以考虑在bean的方法中实现如下:

@AssertTrue
public boolean isValid() {
    //custom validation logic
}

或者,您可以利用Hibernate Validator提供的约束。

有时您需要提出问题,以了解如何自己解决“问题”。根据Gunnar的回答和评论:

您可以使用所有必要的验证器为自定义域模型创建
@MyDomainModelValid
constriant定义:

@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy={
        MyFirstEntityValidator.class, MySecondEntityValidator.class,
        MyThirdEntityValidator.class, EtCetera.class})
public @interface MyDomainModelValid {
    String message() default "entity.notValid";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
}
@Target({TYPE})
@保留(运行时)
@约束(validatedBy)={
MyFirstEntityValidator.class、MySecondEntityValidator.class、,
MyThirdEntityValidator.class,EtCetera.class})
public@interface MyDomainModelValid{
字符串消息()默认为“entity.notValid”;
类[]组()默认值{};

课堂有时你需要问这个问题来了解如何自己解决“问题”。根据Gunnar的回答和评论:

您可以使用所有必要的验证器为自定义域模型创建
@MyDomainModelValid
constriant定义:

@Target({TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy={
        MyFirstEntityValidator.class, MySecondEntityValidator.class,
        MyThirdEntityValidator.class, EtCetera.class})
public @interface MyDomainModelValid {
    String message() default "entity.notValid";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
}
@Target({TYPE})
@保留(运行时)
@约束(validatedBy)={
MyFirstEntityValidator.class、MySecondEntityValidator.class、,
MyThirdEntityValidator.class,EtCetera.class})
public@interface MyDomainModelValid{
字符串消息()默认为“entity.notValid”;
类[]组()默认值{};

好问题,也许他们认为其他框架(如JSF)提供的验证就足够了。好问题,也许他们认为其他框架(如JSF)提供的验证就足够了。
@AssertTrue
在单个方法上不允许特定字段的验证消息(即,您不能构建自己的约束冲突)。
@ScriptAssert
是不可接受的替代方案。但我看到其他解决方案正在阅读您的答案-create