【问题标题】:Can I propagate struts2 ActionErrors between different action classes?我可以在不同的动作类之间传播 struts2 ActionErrors 吗?
【发布时间】:2010-11-07 09:26:14
【问题描述】:

如果我有一个动作,结果是重定向动作到不同类中的另一个动作,是否可以在结果动作中显示验证错误?例如。在以下示例中,如果用户执行 actionA(没有与之关联的视图)并且出现错误,是否有任何方法可以在 actionB 结果(foo.jsp)中显示这些错误?还是我以完全错误的方式解决这个问题?

<package name="a" extends="struts-default" namespace="/a">
    <action name="actionA" class="actionAClass">
        <result name="input" type="redirectAction">
            <param name="actionName">actionB</param>
            <param name="namespace">/b</param>
        </result>
        <result type="redirectAction">
            <param name="actionName">actionB</param>
            <param name="namespace">/b</param>
        </result>
    </action>
</package>
<package name="b" extends="struts-default" namespace="/b">
    <action name="actionB" class="actionBClass">
        <result>/foo.jsp</result>
    </action>
</package>

【问题讨论】:

标签: java model-view-controller error-handling struts2 struts


【解决方案1】:

Struts2 默认有一个存储拦截器。它以 STORE 模式将 actionMessages、actionErrors 和 fieldErrors 存储在 session 中,您可以在 RETRIEVE 模式下使用相同的拦截器在下一次重定向中检索它们。更多详情可查看here

【讨论】:

    【解决方案2】:

    基本上,您必须使用名为 store 的预定义拦截器,它采用 operationMode:存储和检索:

    <package name="a" extends="struts-default" namespace="/a">
        <action name="actionA" class="actionAClass">
            <!-- Here you are storing the Error messages -->
            <interceptor-ref name="store">
                <param name="operationMode">STORE</param>
            </interceptor-ref>
    
            <!-- include your default stack in case you need to load other interceptors -->
            <interceptor-ref name="defaultStack" />
    
            <result name="input" type="redirectAction">
                <param name="actionName">actionB</param>
                <param name="namespace">/b</param>
            </result>
            <result type="redirectAction">
                <param name="actionName">actionB</param>
                <param name="namespace">/b</param>
            </result>
        </action>
    </package>
    <package name="b" extends="struts-default" namespace="/b">
        <action name="actionB" class="actionBClass">
    
            <interceptor-ref name="store">
                <param name="operationMode">RETRIEVE</param>
            </interceptor-ref>
    
            <!-- include your default stack in case you need to load other interceptors -->
            <interceptor-ref name="defaultStack" />
    
            <result>/foo.jsp</result>
        </action>
    </package>
    

    【讨论】:

      【解决方案3】:

      我找到了一个更好的解决方案来传递关于 actionRedirect 结果类型的操作错误和消息。它对我有用。

      <action name="action1" class="action.Action1" >
          <result>/abc.jsp</result>
          <result name="input" type="redirectAction">
          <param name="actionName">action2</param>
          <param name="param1">${param1}</param>
          <param name="param2">${param2}</param>
          <param name="actionErrors">${actionErrors}</param>
          </result>
          </action>
          <action name="action2" class="action.Action2" >
          <result>/def.jsp</result>
          <result name="input">/def.jsp</result>
           </action/>
      

      就是这样......快乐编码

      【讨论】:

      • &lt;param name="actionErrors"&gt;${actionErrors}&lt;/param&gt; 这一切都很神奇。
      • 这是否会同时传递操作错误和消息,还是需要&lt;param name="actionMessages"&gt;${actionMessages}&lt;/param&gt; 才能传递消息?
      • &lt;param name="actionMessages"&gt;${actionMessages}&lt;/param&gt; 确实传递了消息。谢谢!
      • 您应该指出,您将始终以action2的结果“输入”结束,并且不会调用该操作的执行方法...
      【解决方案4】:

      可能有办法做到这一点,但我认为这不是使用 struts 的好方法。如果 actionA 验证失败,您很可能希望有一个显示错误的非重定向输入结果,或者可能需要一个可以显示它的全局错误页面。

      我想您可以将操作错误存储在重定向之间的会话等某处,但您不会真正使用框架的设计方式。

      【讨论】:

        【解决方案5】:

        在第一个操作中使用ActionContext.getContext().getSession().put(key, value),并在主操作的redirectedActionaddActionErrors 中使用ActionContext.getContext().getSession().get(key) 检索它

        【讨论】:

        【解决方案6】:

        如果您在 struts.xml 或 struts.properties 文件中执行以下操作,结果类型链会将消息/错误复制到结果操作 -

        struts.xwork.chaining.copyErrors - set to true to copy Action Errors
        struts.xwork.chaining.copyFieldErrors - set to true to copy Field Errors
        struts.xwork.chaining.copyMessages - set to true to copy Action Messages
        

        示例(struts.xml)-

        <constant name="struts.xwork.chaining.copyErrors" value="true"/>
        

        【讨论】:

          【解决方案7】:

          存储拦截器 (MessageStoreInterceptor) 可用于存储和检索actionErrorsactionMessagesfieldErrors

          您可以通过将operationMode 参数传递给操作来动态更改存储拦截器的操作

          http://localhost/sample.action?operationMode=STORE

          您可以在默认堆栈中将存储拦截器设置为STORE 模式,这使得所有操作消息都可以存储在会话中。

              <interceptor-ref name="store">
                     <param name="operationMode">STORE</param>
              </interceptor-ref>
          

          要获取消息,您需要将 RETRIEVE 模式下的 store 拦截器添加到需要这些消息的特定操作中。

          这是一个重定向到的示例全局错误页面,当我们添加store拦截器并将operationMode设置为RETRIEVE时,此操作可以读取actionErrorsfieldErrorsactionMessages

          @Action(value = "error-page" , 
                          interceptorRefs = 
                            {@InterceptorRef(value = "store", params = {"operationMode", "RETRIEVE"})}
                      )
           public String execute() throws Exception {    
            LOG.error("An error accrued during action ActionErrors '{}' , FieldErrors '{}' " , getActionErrors() , getFieldErrors());
            //Rest of the code
          }
          

          MessageStoreInterceptor 在添加新错误之前删除以前的错误。

          您可以在默认堆栈中设置AUTOMATIC 中的存储。通过这种方式,所有消息都将始终存储并在操作结果类型为ServletRedirectResult 时自动重试(例如,如果操作'redirectAction','redirect')因此您不需要定义显式store 拦截器在RETRIEVE 模式下。

          虽然这不是一个好方法,但您可以使用这些密钥访问会话中的存储消息。

          session.get(MessageStoreInterceptor.fieldErrorsSessionKey)
          session.get(MessageStoreInterceptor.actionErrorsSessionKey)
          session.get(MessageStoreInterceptor.actionMessagesSessionKey)
          

          【讨论】:

            【解决方案8】:

            默认情况下,Struts2 不支持此功能。虽然存在解决方案(它是通过在会话中存储消息的简单 struts 拦截器完成的)。

            solution with source code

            【讨论】:

              【解决方案9】:

              您可以使用结果类型“链”。

              <action name="delete" class="com.example.Delete">   
                  <result name="error" type="chain">
                      <param name="actionName">show</param>
                  </result>           
              </action>   
              <action name="show" class="com.example.Show">
                  <result name="success" type="dispatcher">/jsp/show.jsp</result>                     
              </action>
              

              在 show.jsp 中,您可以显示您在删除操作中设置的操作错误或操作消息

              【讨论】:

              • 不鼓励使用chain
              【解决方案10】:

              这项工作在我身上

              在 struts.xml 中添加这一行:

              <constant name="struts.xwork.chaining.copyErrors" value="true"/>
              <constant name="struts.xwork.chaining.copyMessages" value="true"/>
              

              使用结果类型“链”并添加名称为“输入”的结果:

              <package name="a" extends="struts-default" namespace="/a">
                  <action name="actionA" class="actionAClass">
                      <result name="input" type="chain">
                          <param name="actionName">actionB</param>
                          <param name="namespace">/b</param>
                      </result>
                      <result type="chain">
                          <param name="actionName">actionB</param>
                          <param name="namespace">/b</param>
                      </result>
                  </action>
              </package>
              <package name="b" extends="struts-default" namespace="/b">
                  <action name="actionB" class="actionBClass">
                    <result>/foo.jsp</result>
                    <result name="input">/foo.jsp</result>
                  </action>
              </package>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-04-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多