Java Bean Validation (JSR303) 约束涉及多个 bean 属性之间的关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1700295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Bean Validation (JSR303) constraints involving relationship between several bean properties
提问by Hedenius Access
Say I have the following simple java bean:
假设我有以下简单的 java bean:
class MyBean {
private Date startDate;
private Date endDate;
//setter, getters etc...
}
Is there a mechanism in JSR 303 to create a custom validator that validates the constraint that startDate must be before endDate?
JSR 303 中是否有一种机制来创建自定义验证器来验证 startDate 必须在 endDate 之前的约束?
It seems to me to be a common use case, yet I cannot find any examples of this kind of multiple property relationsship constraint.
在我看来,这是一个常见的用例,但我找不到这种多属性关系约束的任何示例。
回答by McDowell
I can think of a few things to try.
我可以想到一些尝试。
You could create a Constraintwith a target of the type itself with an appropriate validator:
您可以Constraint使用适当的验证器创建具有类型本身的目标:
@ValidateDateRange(start="startDate", end="endDate")
public class MyBean {
You could encapsulate a date range in a type and validate that:
您可以在类型中封装日期范围并验证:
public class DateRange {
private long start;
private long end;
public void setStart(Date start) {
this.start = start.getTime();
}
// etc.
You could add a simple property that performs the check:
您可以添加一个简单的属性来执行检查:
public class MyBean {
private Date startDate;
private Date endDate;
@AssertTrue public boolean isValidRange() {
// TODO: null checks
return endDate.compareTo(startDate) >= 0;
}
回答by Gunnar
If you're using Hibernate Validatorin version 4.1 or later you can use the @ScriptAssertconstraint together with a scripting or expression language to express this kind of constraint. Using JavaScript your example would look like this:
如果您在 4.1 或更高版本中使用Hibernate Validator,您可以将@ScriptAssert约束与脚本或表达式语言一起使用来表达这种约束。使用 JavaScript,您的示例将如下所示:
@ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
public class CalendarEvent {
private Date startDate;
private Date endDate;
//...
}
You can get an even more compact syntax by creating a custom constraintfor the script language of your choice:
您可以通过为您选择的脚本语言创建自定义约束来获得更紧凑的语法:
@JexlAssert("_.startDate < _.endDate")
public class CalendarEvent {
private Date startDate;
private Date endDate;
//...
}
回答by Hardy
The answer is a class level validator. You can define custom constraints which you can place on entity class. At validation time you get passed the whole instance into the isValid() method. You can then compare your two dates against each other. See also the Hibernate Validator documentation.
答案是类级别的验证器。您可以定义可以放置在实体类上的自定义约束。在验证时,您将整个实例传递给 isValid() 方法。然后,您可以将两个日期相互比较。另请参阅 Hibernate Validator文档。
回答by pino
回答by Aaron Digulla
Since there is no way to access the bean in a JSR 303 validator, this is not possible.
由于无法在 JSR 303 验证器中访问 bean,因此这是不可能的。
A workaround would be to supply your own ConstraintValidatorContextand extend it with a reference to the bean you're currently validating. But I'm not sure whether you can modify/override the respective factory.
一种解决方法是提供您自己的ConstraintValidatorContext并使用对您当前正在验证的 bean 的引用来扩展它。但我不确定您是否可以修改/覆盖相应的工厂。

