7

在下面的动作类中,我使用了参数拦截器。

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "struts-default")
@InterceptorRefs(@InterceptorRef(value="store", params={"operationMode", "AUTOMATIC"}))
public final class TestAction extends ActionSupport implements Serializable, ValidationAware, Preparable
{
    private static final long serialVersionUID = 1L;

    private String param1;
    private String param2;

    //Getters and setters.

    public TestAction() {}

    @Action(value = "TestMessage",
        results = {
            @Result(name=ActionSupport.SUCCESS, type="redirectAction", params={"namespace", "/admin_side", "actionName", "Test"}),
            @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
        interceptorRefs={
            @InterceptorRef(value="paramsPrepareParamsStack", params={"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true"})
        })
    public String insert() {
        // Do something. Add or update a row to the database (one at a time).
        addActionMessage("Action message");
        addActionError("Error message");
        return ActionSupport.SUCCESS;
    }

    @Action(value = "Test",
    results = {
        @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
        @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
    public String load() throws Exception {
        // This method is just required to return an initial view on page load.
        return ActionSupport.SUCCESS;
    }

    @Override
    public void prepare() throws Exception {}
}

以下是<s:form>

<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
    <s:if test="hasActionMessages()">
        <s:actionmessage theme="jquery"/>
    </s:if>

    <s:if test="hasActionErrors()">
        <s:actionerror theme="jquery"/>
    </s:if>

    <s:hidden name="param1"/>
    <s:hidden name="param2"/>
    <s:hidden name="extraParam"/>
    <s:submit value="Submit" action="TestMessage"/>
</s:form>

在这里,隐藏的表单字段extraParam没有被声明,因此在 action 类中没有 setter 和 getter。

在这种情况下,当提交此表单时,服务器终端上会出现以下消息。

严重:开发人员通知(将 struts.devMode 设置为 false 以禁用此消息):在“类操作”上设置“extraParam”时捕获意外异常。TestAction:错误设置表达式“extraParam”,值为 ['',]

params.excludeParams不排除extraParam动作类中的参数。

我们可以在使用参数拦截器时以某种方式防止此类异常吗?此类消息不必要地添加到操作消息中,并<s:actionmessage/>在根本不应该显示时通过 显示(如果使用)。


如果在操作类中将其paramsPrepareParamsStack替换为defaultStack,则不会出现此类消息。它只是给出如下警告。

警告:参数 [extraParam] 位于模式的 excludeParams 列表中!

请不要只是说,设置struts.devModefalse禁用此类消息。

4

3 回答 3

2

我已经在评论中说过,如果您定义自己的一组覆盖默认设置的参数,则父包的拦截器配置不会继承拦截器参数。请参阅拦截器参数覆盖继承

还有一些技术用于获取两个不同的拦截器参数映射,请参阅在 Struts2 中获取拦截器参数

约定插件创建从某些父包继承的 XWork 包配置。请参阅我对Struts 2 Convention Plugin Define Multiple Parent Packages的回答。

因此,如果您想将自己的参数添加到集合中,您所要做的就是覆盖父配置设置的默认参数。无论是interceptor标签还是interceptor-stack标签,您都应该为每个interceptor-ref标签执行此操作。

约定插件@InterceprorRef出于相同目的使用注释,但需要注意的是,如果应用于类,它将应用于该类的每个操作。因此,在类级别上使用此注解时要小心。您正在覆盖拦截器堆栈参数,因此您应该为每个参数名称使用堆栈中引用的拦截器名称的前缀后跟点,但这仅interceptor-ref在堆栈中具有唯一名称的情况下才有效。

如果您有两个params拦截器引用,paramsPrepareParamsStack那么您不能覆盖第二个params interceptor-ref,除非您创建自己的拦截器堆栈并在拦截器的每个引用上指定参数覆盖。

于 2014-05-10T11:12:04.450 回答
1

让我们看一下paramsPrepareParamsStack

 <interceptor-stack name="paramsPrepareParamsStack">
      <interceptor-ref name="exception"/>
      <interceptor-ref name="alias"/>
      <interceptor-ref name="i18n"/>
      <interceptor-ref name="checkbox"/>
      <interceptor-ref name="multiselect"/>
      <interceptor-ref name="params">
          <param name="excludeParams">dojo\..*,^struts\..*</param>
      </interceptor-ref>
      <interceptor-ref name="servletConfig"/>
      <interceptor-ref name="prepare"/>
      <interceptor-ref name="chain"/>
      <interceptor-ref name="modelDriven"/>
      <interceptor-ref name="fileUpload"/>
      <interceptor-ref name="staticParams"/>
      <interceptor-ref name="actionMappingParams"/>
      <interceptor-ref name="params">
          <param name="excludeParams">dojo\..*,^struts\..*</param>
       </interceptor-ref>
       <interceptor-ref name="conversionError"/>
       <interceptor-ref name="validation">
           <param name="excludeMethods">input,back,cancel,browse</param>
       </interceptor-ref>
       <interceptor-ref name="workflow">
           <param name="excludeMethods">input,back,cancel,browse</param>
       </interceptor-ref>
 </interceptor-stack>

有2个params拦截器。当您在操作类中设置excludeParams参数时,这可能是为第一个params拦截器设置的 - 第二个拦截器的参数保持默认。现在,当调用第二个params拦截器(默认excludeParams)时,会抛出给定的异常。

您可以尝试复制excludeParams参数的设置以将其也设置为第二个拦截器:

 @InterceptorRef(value = "paramsPrepareParamsStack", params = {"params.acceptParamNames", "param1, param2", "params.excludeParams", "extraParam", "params.excludeParams", "extraParam", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
于 2014-02-16T22:04:32.887 回答
1

具体我说的不

示例代码如下:

<s:form action="save" method="post">
    <s:textfield key="personBean.firstName" /> 
    <s:textfield key="personBean.lastName" /> 
    <s:textfield key="personBean.email" />
    <s:textfield key="personBean.phoneNumber" />
    <s:select key="personBean.sport" list="sports" />
    <s:radio key="personBean.gender" list="genders" />
    <s:select key="personBean.residency" list="states" listKey="stateAbbr" listValue="stateName"/>
    <s:checkbox key="personBean.over21" />
    <s:checkboxlist key="personBean.carModels" list="carModelsAvailable" />
    <s:submit key="submit" />
</s:form>

也许它不起作用转到此链接:

于 2014-02-17T12:51:29.040 回答