我正在尝试在Struts2(2.3.16)中构建自定义验证器,如下所示。
package validator;
import actions.DiscountAction;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.ValidatorSupport;
import org.joda.time.DateTime;
public final class DiscountDateValidator extends ValidatorSupport
{
private DateTime startDate;
private DateTime endDate;
//Getters and setters.
@Override
public void validate(Object o) throws ValidationException
{
System.out.println("startDate = "+startDate);
System.out.println("endDate = "+endDate);
System.out.println((o instanceof DiscountAction));
}
}
validators.xml
文件如下所示。<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator Config 1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd">
<validators>
<validator name="discountDateValidator"
class="validator.DiscountDateValidator"/>
</validators>
并且该验证器用于以下操作。
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value="struts-default")
public final class DiscountAction extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Discount>
{
@Autowired
private final transient DiscountService discountService=null;
private static final long serialVersionUID = 1L;
private Discount entity=new Discount();
@Override
public Discount getModel() {
return entity;
}
@Validations(
customValidators={
@CustomValidator(type="discountDateValidator", parameters={
@ValidationParameter(name="startDate", value="${entity.discountStartDate}"),
@ValidationParameter(name="endDate", value="${entity.discountEndDate}")},
message="xxx zzz aaa")})
@Action(value = "AddDiscount",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", params={"namespace", "/admin_side", "actionName", "Discount", "currentPage", "${currentPage}", "message", "${message}", "editId", "${editId}", "status", "${status}"}),
@Result(name = ActionSupport.INPUT, location = "Discount.jsp")},
interceptorRefs={@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "editId, discountId, discountCode, discountPercent, discountStartDate, discountEndDate, currentPage, rowCount, totalPages, status", "validation.validateAnnotatedMethodOnly", "true"})})
public String insert(){
return ActionSupport.SUCCESS;
}
}
提交表单时将调用
validate()
的DiscountDateValidator
方法,但是startDate
和endDate
的值始终为null
,o instanceof DiscountAction
的计算结果为true
。我在这里俯瞰什么?
最佳答案
这是因为${discountStartDate}
和${discountEndDate}
(@ValidationParameter
的值属性)直接设置为验证器的字符串属性,我们需要使用Object parse(String expression, Class type)
方法中的validate()
方法手动对其进行解析。
通过parse()
方法将此类表达式评估为OGNL表达式。这些更改后的验证器如下。
package validator;
import actions.DiscountAction;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.ValidatorSupport;
import org.joda.time.DateTime;
public final class DiscountDateValidator extends ValidatorSupport
{
private String startDate; //Set to ${discountStartDate}
private String endDate; //Set to ${discountEndDate}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
@Override
public void validate(Object o) throws ValidationException
{
DateTime discountStartDate = (DateTime)parse(startDate, DateTime.class);
DateTime discountEndDate = (DateTime)parse(endDate, DateTime.class);
System.out.println("startDate = "+discountStartDate);
System.out.println("endDate = "+discountEndDate);
System.out.println((o instanceof DiscountAction));
//Perform validation as required using these values.
}
}
getFieldValue("discountStartDate", o)
和getFieldValue("discountEndDate", o)
也可以直接检索字段值(我不确定这种方法在这种验证器中的副作用)。不需要
${entity.discountStartDate}
和${entity.discountStartDate}
(由于问题中包含entity
,因此应将其排除在外)。