在Struts 2中重用自定义表达式验证器

4
在Struts 2中,我们可以开发一个可以在整个应用程序中使用的@CustomValidator
@CustomValidator(type = "CustomerNumberValidator", fieldName = "customerNo")

对于验证 多个 字段,我们使用 @ExpressionValidator

@ExpressionValidator(expression = 
"( (!''.equals(account.firstName) && (!''.equals(account.lastName) )
   || (presonalAccount == false)", 
   key = "validate.account.name")

如果表达式过于复杂,需要处理多个字段,我们使用OGNL调用静态方法。静态方法将进行验证并返回布尔值,例如。
@ExpressionValidator(expression = "@foo.bar.CalendarUtil@compareDates(fromDate,toDate)", key = "validate.date.before")

以下是一些关于it技术的翻译:

上面是一个自定义表达式验证器!

我们在整个应用程序中使用 @foo.bar.CalendarUtil@compareDates 来进行此验证。

是否有另一种方法可以使我们使用自定义的全局验证器?!

是否有任何自定义表达式验证器可以添加到 Struts 中,并且我们可以像使用 @CustomValidator 一样在 Action 中调用它?

2个回答

4
创建自定义验证器(与字段无关):
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 || d2.before(d1)){
            addActionError(getDefaultMessage());
        }
    }
}

validators.xml 文件中注册自定义验证器:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
     "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
     "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
    <validator name="compareDatesValidator" 
              class="org.foo.bar.CompareDatesValidator"/>
</validators>

在操作中使用验证器:

private Date startDate; // getter and setter
private Date endDate;   // getter and setter

@Validations(
    customValidators={
        @CustomValidator(type="compareDatesValidator", 
            message="Dates provided are not valid."
            parameters={
                @ValidationParameter(name="fromDate", value="${startDate}"), 
                @ValidationParameter(name="toDate",   value="${endDate}")})})
public String execute(){
    return SUCCESS;
}

太好了,这正是我在寻找的。您能否更新您的答案并告诉我,在一个i18n应用程序中,如何读取compareDatesValidator中的自定义消息键,并将其设置在addActionError中? - Alireza Fattahi
对我来说,这似乎是另一个问题,因此最好将其作为另一个问题发布(例如“如何从自定义验证器中获取i18n消息”)... - Andrea Ligios
好的,我已经在这里提问了:http://stackoverflow.com/questions/28054378/struts-2-how-to-get-i18n-messages-from-within-a-custom-validator - Alireza Fattahi

1
你可以使用非字段自定义验证器来验证多个字段。非字段自定义验证器应该扩展ValidatorSupport并实现validate方法。然后在你的-validation.xml中应用自定义验证器,或者使用@CustomValidator注释。在那里,你可以添加自定义表达式作为@ValidationParameter,并在验证时解析它们。
注意: 我在this答案中首次使用了这种技术。
public class RetypeValidator extends ValidatorSupport {

  private String value = null;

  public String getValue() {
    return value;
  }
  public void setValue(String value) {
    this.value = value;
  }

  private String retypeValue = null;

  public String getRetypeValue() {
    return retypeValue;
  }

  public void setRetypeValue(String value) {
    retypeValue = value;
  }

  @Override
  public void validate(Object object) throws ValidationException {
    String value = (String) parse(this.value, String.class);
    String retypeValue = (String) parse(this.retypeValue, String.class);
    if (value != null && retypeValue != null && !value.equals(retypeValue))
      addActionError(getDefaultMessage());
  }
}
另一种选择是覆盖 ActionSupport 类的 validate 方法。通过 validation 拦截器 控制对该方法的调用。这种验证方法被称为编程式验证,并且默认情况下无论在声明式验证期间应用了哪些验证器都会使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接