如何短路@CustomValidator?

How to short-circuit a @CustomValidator?

考虑下面的示例,它检查 fromDatetoDate 是否是有效日期以及 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 扩展了 FieldValidatorSupportCompareDatesValidator 扩展了 ValidatorSupport

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

正如解释的那样in the documentation

Plain validator takes precedence over field-validator. They get validated first in the order they are defined and then the field-validator in the order they are defined. Failure of a particular validator marked as short-circuit will prevent the evaluation of subsequent validators and an error (action error or field error depending on the type of validator) will be added to the ValidationContext of the object being validated.

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

  1. CompareDatesValidator(普通)
  2. DateValidator(字段fromDate
  3. DateValidator(字段toDate

问题是它会先执行,但是由于它的检查是基于两个字段的复合检查,所以应该先对字段本身进行原子检查。

但这就是框架的工作原理,所以你需要解决方法

If (even if with ),如果输入无效,您可以避免检查并忽略错误,让此验证发生在它所属的地方,在字段验证器中:

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());
        }
    }
}

您只需要记住始终将 Field Validators 放在与 CompareDatesValidator 或 [=28] 相同的验证堆栈中=]"Date not valid" 错误将被默默吞噬。