在Hibernate Validator 4.x中是否有(或第三方实现)交叉字段验证的实现?如果不是,那么实现交叉字段验证器的最简洁方法是什么?
例如,如何使用API来验证两个bean属性是否相等(例如验证密码字段是否与密码验证字段匹配) .
在注释中,我希望有类似的东西:
public class MyBean {
@Size(min=6, max=50)
private String pass;
@Equals(property="pass")
private String passVerify;
}
15 回答
每个字段约束应该由不同的验证器注释处理,或者换句话说,它应该对其他字段进行验证注释检查;跨领域验证应在 class 进行 . 此外,JSR-303 Section 2.2表达相同类型的多个验证的首选方式是通过注释列表 . 这允许每次匹配指定错误消息 .
例如,验证常见表单:
注释:
验证者:
我建议你另一个可能的解决方案也许不那么优雅,但更容易!
isValid()方法由验证程序自动调用 .
我很惊讶这是开箱即用的 . 无论如何,这是一个可能的解决方案 .
我已经创建了一个类级别验证器,而不是原始问题中描述的字段级别 .
这是注释代码:
验证器本身:
请注意,我已使用MVEL检查要验证的对象的属性 . 这可以用标准反射API替换,或者如果它是您正在验证的特定类,则访问器方法本身 .
然后可以在bean上使用@Matches注释,如下所示:
作为免责声明,我在最后5分钟写了这篇文章,所以我可能还没有解决所有的错误 . 如果出现任何问题,我会更新答案 .
使用Hibernate Validator 4.1.0.Final我建议使用@ScriptAssert:
自定义类级验证器@Matches解决方案没有问题 .
可以通过创建自定义约束来完成跨字段验证 .
示例: - 比较User实例的password和confirmPassword字段 .
CompareStrings
StringComparisonMode
CompareStringsValidator
ConstraintValidatorHelper
User
Test
Output
Message:- [Password, ConfirmPassword] must be equal.
通过使用CompareStrings验证约束,我们还可以比较两个以上的属性,并且我们可以混合四种字符串比较方法中的任何一种 .
ColorChoice
Test
Output
Message:- Please choose three different colors.
同样,我们可以使用CompareNumbers,CompareDates等跨字段验证约束 .
P.S. 我没有在 生产环境 环境下测试过这段代码(虽然我在开发环境下对它进行了测试),所以请将此代码视为Milestone Release . 如果您发现了错误,请写一个好评 . :)
我试过Alberthoven的例子(hibernate-validator 4.0.2.GA),我得到一个ValidationException:“带注释的方法必须遵循JavaBeans命名约定 . match()没有 . “也是 . 将方法从“匹配”重命名为“isValid”后,它可以正常工作 .
如果您正在使用Spring Framework,那么您可以使用Spring Expression Language(SpEL) . 我写了一个小型库,它提供了基于SpEL的JSR-303验证器 - 它使得跨场验证变得轻而易举!看看https://github.com/jirutka/validator-spring .
这将验证密码字段的长度和相等性 .
您也可以轻松修改此选项,以便仅在不为空时才验证密码字段 .
使用此dedicated JSR-303 constraint library中的@EqualProperties:
我没有评论第一个答案的声誉,但想补充一点,我已经为获胜答案添加了单元测试,并有以下观察:
我喜欢Jakub Jirutka使用Spring Expression Language的想法 . 如果你不想添加另一个库/依赖项(假设你已经使用了Spring),这里是他的想法的简化实现 .
约束:
验证者:
像这样申请:
非常好的解决方案bradhouse . 有没有办法将@Matches注释应用于多个字段?
编辑:这是我提出的解决这个问题的解决方案,我修改了Constraint以接受数组而不是单个值:
注释的代码:
并实施:
你需要明确地称它 . 在上面的示例中,bradhouse为您提供了编写自定义约束的所有步骤 .
在您的调用者类中添加此代码 .
在上述情况下,它将是
为什么不试试Oval:http://oval.sourceforge.net/
我看起来它支持OGNL所以也许你可以通过更自然的方式来实现它
你们真棒 . 真的很棒的想法 . 我最喜欢 Alberthoven's 和 McGin's ,所以我决定结合这两个想法 . 并开发一些通用解决方案来满足所有情况 . 这是我提出的解决方案 .
解决方案与问题:How to access a field which is described in annotation property
以及如何使用它?像这样: