考虑下面的示例,它检查fromDate
和toDate
是否为有效日期,以及fromDate
是否小于toDate
:
@CustomValidator(type = "DateValidator",
fieldName = "fromDate",
shortCircuit = true),
@CustomValidator(type = "DateValidator",
fieldName = "toDate",
shortCircuit = true),
@CustomValidator(type = "CompareDatesValidator",
message = "validate.date.jalali.same.or.before",
shortCircuit = true,
parameters = {
@ValidationParameter(name = "fromDateParam", value = "${fromDate}"),
@ValidationParameter(name = "toDateParam", value = "${toDate}")
})
DateValidator
扩展FieldValidatorSupport
,CompareDatesValidator
扩展ValidatorSupport
虽然我有shortCircuit
的DateValidator
,但CompareDatesValidator
总是运行,这是不正确的。我能修好吗?!
如文档中所述。
普通验证器优先于字段验证器它们首先按照定义顺序进行验证,然后按照定义顺序对字段验证器进行验证。标记为短路的特定验证器的故障将阻止后续验证器的评估,并且一个错误(操作错误或字段错误,取决于验证器的类型)将添加到被验证对象的ValidationContext中。
那么您的实际执行顺序是:
- CompareDatesValidator(纯文本)
-
日期验证器(字段
fromDate
) -
日期验证器(字段
toDate
)
问题是它将首先执行,但由于它的检查是基于两个字段的复合检查,因此应该首先执行字段本身的原子检查。
但这就是框架的工作方式,所以您需要解决方法它。
如果你的普通验证器仍然是这个(即使有一些修改),你可以避免检查并忽略错误,以防输入无效,让这个验证发生在它所属的地方,在字段验证器中:
public final class CompareDatesValidator extends ValidatorSupport {
private String fromDate; // getter and setter
private String toDate; // getter and setter
@Override
public void validate(Object o) throws ValidationException {
Date d1 = (Date)parse(fromDate, Date.class);
Date d2 = (Date)parse(toDate, Date.class);
if (d1==null || d2==null){
LOG.debug("Silently disabling Plain Validator. Check performed by Field ones");
} else if (d2.before(d1)){
addActionError(getDefaultMessage());
}
}
}
您只需要记住始终将字段验证器放在CompareDatesValidator的同一验证堆栈中,否则"日期无效"错误将被静默地吞噬。