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

时间:2014-01-19 21:29:57

标签: 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 boolean isValid() {
        return password.equals(confirmation);
    }
}

但我真正想要的是这样的:

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

    @NotNull
    public String confirmation;
}

因此错误消息将在字段级别设置,而不是在类/类型级别设置。

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

提前致谢!

解:

感谢Gunnar!我刚刚提出了一个很好的通用解决方案:-)。我只是使用(意味着复制和粘贴)来自Hibernates @ScriptAssertScriptAssertValidator的代码并稍加修改:

@ScriptAssert

  • 添加新的String field()。 (这是附加错误消息的地方)

ScriptAssertValidator

  • initialize方法中,请务必同时保存fieldNamemessage属性,因为我们需要在下一步中访问它们

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

    context.buildConstraintViolationWithTemplate(errorMessage) .addPropertyNode(fieldName).addConstraintViolation();

  • 还要在context.disableDefaultConstraintViolation();方法中的某处添加isValid,以便不生成默认错误消息,否则将在类级别附加其他内容。

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

@FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

简单回答:它不是(除非你实现它):http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html显示所有注释约束。 当然,您可以通过@producer等将您的字符串作为资源注入到您的类中(最近讨论将在jdk8中删除),但是您不能将此值用于您的断言。
回复评论:
这是假设自然是一个常量字符串,你想用它作为一个字符串资源。当然,你可以编写自己的类,基于java.lang.string与@Producer,然后是@Inject - 能够。虽然这肯定不是我个人处理常量字符串的方式。

答案 2 :(得分:1)

如果您正在使用Spring Framework,那么作为使用JSR 223脚本的@ScriptAssert的替代方法,您可以使用使用Spring Expression Language(SpEL)的@SpELAssert 。优点是它不需要任何JSR 223兼容的脚本引擎,这些引擎可能在某些环境中不可用。有关详细信息,请参阅this answer