You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Struts2升级至6.3.0.2后chain结果类型丢失actionMessages问题咨询

Struts2升级后Chain结果类型丢失ActionMessages问题

问题场景

我通过以下代码添加ActionMessages:

this.addActionMessage("alert:" + getText("message.display.Sucess"));

Struts配置如下:

<action name="resetpass" method="resetpass" class="com.UserAction">
    <result type="chain">usersAdmin</result>
</action>

<action name="usersAdmin" method="usersAdmin" class="com.UserAction">
<result name="List">/jsp/templates/admin/user/UserAdmin.jsp
</result>

使用Struts2 2.5.33时,点击重置按钮后alert可正常显示;但升级至6.3.0.2后,调用新action时actionMessages值为null,无法保留。我了解到chain结果类型会重建请求和action上下文,但为何旧版本无此问题?

已尝试的临时方案:显式添加store拦截器(STORE/RETRIVE)可保留值,使用request.setAttribute("message",this.getActionMessages())也有效,但这类操作在多处使用不太合适。


变更原因

Struts2 6.x系列对Chain结果类型的上下文传递机制做了严格规范。在2.5.x版本中,Chain结果会默认将原Action的ActionMessages、ActionErrors等消息对象,通过ActionContext的内部映射直接传递给后续Action;但6.x版本为了遵循Servlet规范的请求隔离原则,修复了Chain结果中跨Action上下文数据泄露的潜在问题,默认不再自动传递这些消息对象,而是要求开发者显式声明数据传递规则。

合适的修复方案

方案1:全局配置Store拦截器(推荐)

在struts.xml中配置全局拦截器栈,将store拦截器加入,统一处理消息传递:

<interceptors>
    <interceptor-stack name="defaultStack">
        <interceptor-ref name="store">
            <param name="operationMode">AUTOMATIC</param>
        </interceptor-ref>
        <!-- 保留原有的默认拦截器 -->
        <interceptor-ref name="defaultStack"/>
    </interceptor-stack>
</interceptors>

AUTOMATIC模式会自动在Chain结果的前后完成消息的存储与恢复,无需在每个Action单独配置。

方案2:针对单个Action配置Store拦截器

如果不需要全局生效,可在涉及Chain跳转的Action中单独配置:

<action name="resetpass" method="resetpass" class="com.UserAction">
    <interceptor-ref name="store">
        <param name="operation">STORE</param>
    </interceptor-ref>
    <interceptor-ref name="defaultStack"/>
    <result type="chain">usersAdmin</result>
</action>

<action name="usersAdmin" method="usersAdmin" class="com.UserAction">
    <interceptor-ref name="store">
        <param name="operation">RETRIEVE</param>
    </interceptor-ref>
    <interceptor-ref name="defaultStack"/>
    <result name="List">/jsp/templates/admin/user/UserAdmin.jsp</result>
</action>

方案3:使用Struts2的MessageStore接口(代码层面优化)

如果不想依赖拦截器,可在Action中通过MessageStore工具类显式处理消息传递,避免直接操作request:

// 在resetpass方法中存储消息
MessageStore messageStore = ActionContext.getContext().get(MessageStore.class);
if (messageStore != null) {
    messageStore.store(ActionContext.getContext());
}

// 在usersAdmin方法中恢复消息
MessageStore messageStore = ActionContext.getContext().get(MessageStore.class);
if (messageStore != null) {
    messageStore.retrieve(ActionContext.getContext());
}

内容的提问来源于stack exchange,提问作者priya Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:12:27