【问题标题】:How to short-circuit a @CustomValidator?如何短路@CustomValidator?
【发布时间】:2016-03-29 22:28:22
【问题描述】:

考虑下面的示例,它检查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

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

【问题讨论】:

  • 这是否回答了您的问题?来自文档: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..
  • @AleksandrM 谢谢我已经看到了,但不幸的是它没有帮助。验证应该是短路的,但不是!
  • Plain validator takes precedence over field-validator. - 意味着您的CompareDatesValidator 将首先执行。这意味着只有在那之后才会发生短路。将其转换为字段验证器,它应该可以按照您的意愿工作。
  • @AleksandrM 评论少,回答多 FTW! :)
  • 我想因为我想在验证期间使用多个字段,所以我应该使用扩展ValidatorSupport。好吧,我将CompareDatesValidator 更改为扩展FieldValidatorSupport,但我从strust 得到Null pointer 你需要stacktarce 吗?!

标签: java validation struts2 struts-validation struts2-convention-plugin


【解决方案1】:

正如in the documentation 解释的那样。

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

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

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

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

但这就是框架的工作方式,因此您需要解决方法

如果your plain validator is still this one(即使使用some modification),您可以避免检查并在输入无效的情况下忽略错误,让此验证发生在字段验证器中它所属的位置:

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 的同一验证堆栈中,或者 “日期无效” 错误会被默默吞下。

【讨论】:

  • DateValidator 是复杂的函数,所以我最终在CompareDatesValidator 中重复了DateValidator。点赞:if( !valid(d1) || !valid(d2)) { LOG.debug("Silently disabling Plain Validator. Check performed by Field ones");} 谢谢解答
猜你喜欢
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多