我可以在不同的操作类之间传播struts2 ActionErrors吗?

时间:2009-07-01 16:29:13

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

如果我有一个动作,其结果是redirectAction到另一个类中的另一个动作,是否有可能在结果动作中显示验证错误?例如。在下面的示例中,如果用户执行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>

10 个答案:

答案 0 :(得分:11)

默认情况下,Struts2有一个商店拦截器。它在STORE模式下将actionMessages,actionErrors和fieldErrors存储在会话中,您可以通过在RETRIEVE模式下使用相同的拦截器在下一个重定向中检索相同的内容。可以找到更多详细信息here

答案 1 :(得分:7)

基本上你必须使用名为store的预定义拦截器,它接受operationMode:store和retrieve:

<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>

答案 2 :(得分:6)

我找到了一个更好的解决方案,可以在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/>

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

答案 3 :(得分:4)

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

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

答案 4 :(得分:3)

如果您在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"/>

答案 5 :(得分:2)

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

进行检索

答案 6 :(得分:1)

商店拦截器(\")可用于存储和检索MessageStoreInterceptoractionErrorsactionMessages

您可以通过将fieldErrors参数传递给操作

来动态更改商店拦截器的操作

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

您可以在默认堆栈中以operationMode模式设置商店拦截器,以便将所有操作消息存储在会话中。

STORE

要获取将 <interceptor-ref name="store"> <param name="operationMode">STORE</param> </interceptor-ref> 模式中的store拦截器添加到需要这些消息的特定操作所需的消息。

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

RETRIEVE

@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时会自动重试(例如,如果动作'redirectAction','redirect')那么你不需要定义一个明确的{{ 1}} ServletRedirectResult模式下的拦截器。

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

store

答案 7 :(得分:0)

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

solution with source code

答案 8 :(得分:0)

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

<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中

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

答案 9 :(得分:0)

这项工作在我身上

在struts.xml中添加以下行:

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

使用结果类型&#34;链&#34;并使用名称&#34;输入&#34;添加结果:

<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>