2

考虑下面的示例,它检查是否是有效日期以及fromDate是否小于:toDatefromDatetoDate

@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延伸FieldValidatorSupportCompareDatesValidator延伸_ValidatorSupport

虽然我有shortCircuits DateValidator,但 CompareDatesValidator总是运行,这是不正确的。我可以解决这个问题吗?!

4

1 回答 1

2

文档中所述

普通验证器优先于字段验证器。它们首先按照定义的顺序进行验证,然后按照定义的顺序进行字段验证。标记为短路的特定验证器的失败将阻止对后续验证器的评估,并且将向正在验证的对象的 ValidationContext 添加错误(操作错误或字段错误,具体取决于验证器的类型)。

那么你的实际执行顺序是:

  1. 比较日期验证器(普通)
  2. 日期验证器(字段fromDate
  3. 日期验证器(字段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的同一验证堆栈中,否则“日期无效”错误将被默默吞下。

于 2015-12-23T17:18:21.470 回答