跳过Struts2中某些字段的验证

时间:2013-12-28 18:09:22

标签: java validation struts2

例如,有一个动作类如下。

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@InterceptorRefs({@InterceptorRef(value="defaultStack", params={"validation.excludeMethods", "load"})})
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Transporter>
{
    @Autowired
    private final transient TransporterService transporterService=null;
    private static final long serialVersionUID = 1L;

    private Boolean deleteOneRow=false; //Getter and setter.
    private Transporter entity=new Transporter(); //Getter and setter.
    private List<Transporter>transporters=new ArrayList<Transporter>();
    private String message; //Getter and setter.
    private List<Long>chk; //Getter and setter.

    @Action(value = "Transporter", results = {@Result(name=ActionSupport.SUCCESS, location="Transporter.jsp"), @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")})
    public String load() throws Exception
    {
        return ActionSupport.SUCCESS;
    }

    @Validations(
            requiredStrings={
                @RequiredStringValidator(fieldName="transporterName", type= ValidatorType.FIELD, key = "transporter.name.required"),
                @RequiredStringValidator(fieldName="transporterWebsite", type= ValidatorType.FIELD, key = "transporter.website.required")},
            stringLengthFields={
                @StringLengthFieldValidator(fieldName="transporterName", type= ValidatorType.FIELD, minLength="2", maxLength="45", key="transporter.name.length", messageParams={"2", "45"}),
                @StringLengthFieldValidator(fieldName="transporterWebsite", type= ValidatorType.FIELD, minLength="10", maxLength="1000", key="transporter.website.length", messageParams={"10", "1000"})})
    @Action(value = "addTransporter",
        results = {@Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.jsp", params={"namespace", "/admin_side", "actionName", "Transporter", "message", "${message}"}),
        @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
        interceptorRefs={@InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterName, transporterWebsite", "validation.validateAnnotatedMethodOnly", "true"})})
    public String insert()
    {
        if(entity.getTransporterId()==null)
        {
            transporterService.insert(entity.getTransporterName(), entity.getTransporterWebsite());
            setMessage(getText("insert.success"));
        }
        else
        {
            setMessage(transporterService.update(entity)?getText("update.success", new String[]{String.valueOf(entity.getTransporterId())}) :getText("update.failed", new String[]{String.valueOf(entity.getTransporterId())}));
        }
        return ActionSupport.SUCCESS;
    }

    @Validations(requiredFields={@RequiredFieldValidator(fieldName="transporterId", type= ValidatorType.FIELD, key = "delete.id.missing")})
    @Action(value = "editTransporter",
            results = {
                @Result(name=ActionSupport.SUCCESS, location="Transporter.jsp"),
                @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
            interceptorRefs={
                @InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterId, transporterName, transporterWebsite", "validation.validateAnnotatedMethodOnly", "true"}),
                @InterceptorRef(value="conversionError")})
    public String edit()
    {
        return ActionSupport.SUCCESS;
    }

    @Action(value = "deleteTransporter",
            results = {
                @Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.action", params={"message", "${message}"}),
                @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
            interceptorRefs={
                @InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "transporterId, deleteOneRow", "validation.validateAnnotatedMethodOnly", "true"}),
                @InterceptorRef(value="conversionError")})
    public String deleteTransporter()
    {
        if(transporterService.delete(entity.getTransporterId()))
        {
            //Pagination has not not yet been implemented. Hence, it is static.
            transporters=transporterService.getList(0, 20); 
            setMessage(getText("delete.success", new String[]{String.valueOf(entity.getTransporterId())}));
        }
        else
        {
            setMessage(getText("delete.failed", new String[]{String.valueOf(entity.getTransporterId())}));
        }
        return ActionSupport.SUCCESS;
    }

    @Action(value = "deleteTransporters",
            results = {
                @Result(name=ActionSupport.SUCCESS, type="redirectAction", location="Transporter.jsp", params={"namespace", "/admin_side", "actionName", "Transporter", "message", "${message}"}),
                @Result(name = ActionSupport.INPUT, location = "Transporter.jsp")},
            interceptorRefs={
                @InterceptorRef(value="defaultStack", params={"params.acceptParamNames", "chk", "validation.validateAnnotatedMethodOnly", "true"}),
                @InterceptorRef(value="conversionError")})
    public String deleteTransporters()
    {
        setMessage(transporterService.delete(chk)?getText("delete.multiple.success", new String[]{String.valueOf(chk.size())}) :getText("delete.multiple.failed"));
        return ActionSupport.SUCCESS;
    }

    @Override
    public Transporter getModel() {
        return entity;
    }

    public List<Transporter> getTransporters()
    {
        if(CollectionUtils.isEmpty(transporters))
        {
            //Pagination has not not yet been implemented. Hence, it is static.
            transporters=transporterService.getList(0, 20);
        }
        return transporters;
    }

    public void setTransporters(List<Transporter> transporters) {
        this.transporters = transporters;
    }

    @Override
    public void validate(){}
}

JSP页面:

<s:form namespace="/admin_side" action="Transporter" id="dataForm" name="dataForm" cssClass="search_form general_form">
    <s:if test="hasFieldErrors()">
        <s:fielderror fieldName="transporterId"/>
        <s:fielderror fieldName="chk"/>
    </s:if>

    <s:property value="message"/>
    <s:hidden id="transporterId" name="transporterId"/>
    <s:hidden id="deleteOneRow" name="deleteOneRow"/>

   <s:textfield id="transporterName" name="transporterName"/><s:fielderror fieldName="transporterName"/>
   <s:textfield id="transporterWebsite" name="transporterWebsite"/><s:fielderror fieldName="transporterWebsite"/>
   <s:submit id="btnSubmit" name="btnSubmit" value="Submit" action="addTransporter"/>

   <table cellpadding="0" cellspacing="0" width="100%">
        <tbody>
            <tr class="even">
                <th style="width: 96px;">Check</th>
                <th style="width: 96px;">Id</th>
                <th style="width: 96px;">Transporter</th>
                <th style="width: 96px;">Website</th>
                <th style="width: 96px;">Actions</th>
            </tr>
            <s:iterator value="transporters" status="loopStatus">
                <tr class="<s:if test="#loopStatus.odd == true ">first</s:if> <s:else>second</s:else>">
                    <td><s:checkbox name="chk" fieldValue="%{transporterId}" value="false"/></td>
                    <td><s:property value="transporterId" /></td>
                    <td><s:property value="transporterName" /></td>
                    <td>
                        <a href="<s:property value="transporterWebsite" />">Visit</a>
                    </td>
                    <td>
                        <div class='actions'>
                            <ul>
                                <li>
                                    <s:url id="editURL" action="editTransporter" escapeAmp="false">
                                        <s:param name="transporterId" value="%{transporterId}"/>
                                        <s:param name="transporterName" value="%{transporterName}"/>
                                        <s:param name="transporterWebsite" value="%{transporterWebsite}"/>
                                    </s:url>
                                    <s:a href="%{editURL}" cssClass="action2"/>
                                </li>

                                <li>
                                    <s:url id="deleteURL" action="deleteTransporter" escapeAmp="false">
                                        <s:param name="transporterId" value="%{transporterId}"/>
                                        <s:param name="deleteOneRow" value="%{deleteOneRow}"/>
                                    </s:url>
                                    <s:a href="%{deleteURL}" onclick="return deleteOne(%{transporterId});" cssClass="action4"/>
                                </li>
                            </ul>
                        </div>
                    </td>
                </tr>
            </s:iterator>
        </tbody>
    </table>

<s:submit name="btnDelete" id="btnDelete" action="deleteTransporters" onclick="return getCheckedRows();" />

insert()方法接受两个参数transporterNametransporterWebsite,而edit()方法只接受一个参数transporterId,该参数作为查询字符串提供,点击链接时。

insert()方法由<s:submit>的操作映射,而edit()方法由<s:url>的操作映射,其id被赋予href的{​​{1}}属性。

单击编辑链接<s:a>时,文本字段<s:a>transporterName都会被不必要地验证,编辑时不得发生这种情况,即应跳过对这些文本字段的验证/单击编辑链接时禁用。

只应验证transporterWebsite方法接受的transporterId。单击编辑链接时,不应验证其他字段。

在这种情况下,注释edit()不起作用。

怎么做?

1 个答案:

答案 0 :(得分:1)

这是因为我在我定义的类级别验证拦截器中缺少validateAnnotatedMethodOnly

当我将类定义修改为类似以下内容时,它起作用了。

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@InterceptorRefs({@InterceptorRef(value="defaultStack", params={"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public final class TestAction  extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Transporter>
{
    //...
}

我在方法级别包含validation.validateAnnotatedMethodOnly但忘记将其包含在班级中。

使用load()仅在动作类中注释@SkipValidation方法也是合适的,并完全删除类级@InterceptorRefs注释。


来自documentation

  

当使用多个方法来映射相同的不同操作时   class,其中一个用@Validations注释,那些   除非它们是,否则将针对所有操作触发验证器   已设置注释@SkipValidationvalidateAnnotatedMethodOnly   在validation拦截器中为true,如:

<interceptor-ref name="validation">
    <param name="validateAnnotatedMethodOnly">true</param>
    <param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
相关问题