Java 将类型级别验证错误消息附加到特定字段

Java 将类型级别验证错误消息附加到特定字段,java,validation,bean-validation,hibernate-validator,Java,Validation,Bean Validation,Hibernate Validator,我有一个简单的类,它使用boolean isValid()方法进行验证,该方法有效,当然错误消息在类/类型级别 下面是我的简单课程: public class NewPasswordDTO { @NotNull public String password; @NotNull public String confirmation; @AssertTrue(message="Passwords must match.") protected bo

我有一个简单的类,它使用
boolean isValid()
方法进行验证,该方法有效,当然错误消息在类/类型级别

下面是我的简单课程:

public class NewPasswordDTO {
    @NotNull
    public String password;

    @NotNull
    public String confirmation;

    @AssertTrue(message="Passwords must match.")
    protected boolean isValid() {
        return password.equals(confirmation);
    }
}
但我真正想要的是这样的东西:

public class NewPasswordDTO {
    @NotNull
    @Equals("confirmation", message="...")
    public String password;

    @NotNull
    public String confirmation;
}
@FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }
因此,错误消息将设置在字段级别,而不是类/类型级别

这有可能吗?可能对该类使用自定义验证器

提前谢谢

解决方案: 多亏了刚纳!我刚刚提出了一个很好的通用解决方案
:-)
。我只是使用了Hibernates
@ScriptAssert
ScriptAssertValidator
中的代码(意思是复制和粘贴),并对其进行了轻微修改:

@ScriptAssert

  • 添加新的
    字符串字段()。(这是附加错误消息的地方)
ScriptAssertValidator

  • initialize
    方法中,确保还保存
    fieldName
    message
    属性,因为我们需要在下一步中访问它们

  • 将此代码段添加到
    isValid
    方法的底部:

    context.buildConstraintViolationWithTemplate(错误消息)
    .addPropertyNode(字段名).addConstraintViolation()

  • 同时添加
    context.disableDefaultConstraintViolation()方法中的某个地方,code>是有效的
    方法,不会生成默认错误消息,否则会在类级别追加该消息

就这样。现在我可以这样使用它:

public class NewPasswordDTO {
    @NotNull
    @Equals("confirmation", message="...")
    public String password;

    @NotNull
    public String confirmation;
}
@FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }
简单回答:它不是(除非您实现它):显示所有注释约束。 当然,您可以通过@producer等将字符串作为资源注入类中(最近在jdk8中讨论了将其删除),但不能将此值用于断言
回复评论:
这意味着性质是一个常量字符串,您希望将其用作字符串资源。然后,当然可以基于java.lang.string编写自己的类,并使用@Producer,然后使用@Inject-able。虽然这肯定不是我个人处理常量字符串的方式。

简单回答:不是(除非您实现它):显示所有注释约束。 当然,您可以通过@producer等将字符串作为资源注入类中(最近在jdk8中讨论了将其删除),但不能将此值用于断言
回复评论:

这意味着性质是一个常量字符串,您希望将其用作字符串资源。然后,当然可以基于java.lang.string编写自己的类,并使用@Producer,然后使用@Inject-able。虽然这肯定不是我个人处理常量字符串的方式。

您也可以在类上使用
@ScriptAssert
约束(注意,约束应该总是没有副作用的,因此改变已验证bean的状态不是一个好主意;相反,您应该只检查两个字段是否匹配)或者实现自定义类级别约束


后者指向约束冲突的自定义属性路径,它允许将“确认”属性标记为错误而不是完整类。

您可以在类上使用
@ScriptAssert
约束(请注意,约束应该始终没有副作用,因此改变已验证bean的状态不是一个好主意;相反,您应该只检查两个字段是否匹配)或者实现自定义类级约束


后者指向约束冲突的自定义属性路径,它允许标记“确认”属性,而不是完整的类。

如果您使用的是Spring框架,那么作为使用脚本的
@ScriptAssert
的替代方法,您可以使用使用Spring表达式语言(SpEL)的。优点是它不需要任何JSR 223兼容的脚本引擎,而这些引擎在某些环境中可能不可用。有关更多信息,请参阅。

如果您使用的是Spring框架,那么作为使用脚本的
@ScriptAssert
的替代方案,您可以使用使用Spring表达式语言(SpEL)的。优点是它不需要任何JSR 223兼容的脚本引擎,而这些引擎在某些环境中可能不可用。有关更多信息,请参阅。

谢谢。我知道所有这些注释,问题更像是:我可以编写自己的注释/验证程序来处理此问题吗?…我真的不明白您的意思“当然你可以通过@producer等将你的字符串作为资源注入到你的类中。”你有没有一个例子?哇,这听起来真的很像Baaad hack
:-D
。难道不可能在我的任务中使用
@ScriptAssert(…)
也许有可能这样做:
@ScriptAssert(lang=“javascript”,script=“if(!\u this.password.equals(\u this.confirmation))password='';return true;”)
。然后我会让一些
@NotEmpty
检查
密码
,它捕捉到了新引发的错误…我在顶部附加了我的自定义解决方案。我决定使用
@ScriptAssert
的逻辑,而不是死板的自定义注释。非常棒!!谢谢。我知道所有这些注释,问题更像是:我可以写我自己的注释/验证器来处理这个问题吗?…我真的不明白你说的“当然,你可以通过@producer将你的字符串作为资源注入到你的类中,等等”是什么意思“。你有一个例子吗?哇,听起来真像是一个Baaad黑客
:-D
。难道不可能用
@ScriptAssert(…)
来完成我的任务吗?…(它也很脏,但是