首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Struts 2 Action 轉發導致 Request 對象丟失的解決方案

     編輯:程式設計疑難解答

問題現象

用戶在 Struts 2 應用中遇到頁面跳轉異常:

  1. 首次進入頁面正常。
  2. 點擊「考生成績查詢」跳轉正常。
  3. 再點擊「管理員信息管理」時頁面數據丟失,懷疑是 request 對象丟失。

首頁 成績查詢頁 信息管理頁異常

根因分析

Struts 2 默認使用 Action 鏈 或 Result 類型為 chain/redirectAction 時會創建新的 ActionContext 和 HttpServletRequest。若在 Action 中直接往 request.setAttribute(...) 存數據,然後通過 chain 結果跳轉到另一個 Action,原 request 域數據將不可用,因為攔截器鏈重新初始化了上下文。

解決方案

方案一:使用 Session 域(不推薦濫用)

將需跨請求共享的數據放入 Session,用完及時移除。

// Action A
Map<String, Object> session = ActionContext.getContext().getSession();
session.put("userData", data);
return "success"; // chain 到 Action B

// Action B
Map<String, Object> session = ActionContext.getContext().getSession();
Object data = session.remove("userData"); // 取出即刪除,避免殘留

方案二:使用 redirectAction 傳參(推薦)

通過 URL 參數傳遞必要標識(如 ID),目標 Action 重新查詢數據,符合 REST 風格,無狀態。

<result name="success" type="redirectAction">
    <param name="actionName">adminInfoManage</param>
    <param name="studentId">${studentId}</param>
</result>

方案三:ActionContext 手動傳遞(僅限 chain 結果)

若必須用 chain,可在源 Action 的 execute() 結束前,將數據放入 ActionContext.getContext().put(key, value),目標 Action 通過 ActionContext.getContext().get(key) 獲取。注意:chain 結果會複製上下文,但某些版本不複製 request 域。

方案四:改用 MessageStore 拦截器 (Struts 2.3+)

啟用 store 拦截器,自動將 Action 屬性存入 Session 供下一個請求讀取,支持 redirect 和 chain。

<interceptor-ref name="defaultStack">
    <interceptor-ref name="store">
        <param name="operationMode">STORE</param>
    </interceptor-ref>
</interceptor-ref>
<result name="success" type="redirectAction">...</result>

最佳實踐建議

  • 優先選擇 redirectAction + 參數傳遞,避免服務端狀態同步問題。
  • 若涉及大量表單數據回顯,考慮 PRG 模式 (Post-Redirect-Get) 配合 Flash Scope (Struts2 的 messageStore)。
  • 檢查 struts.xml 中 Result 類型,確認是否誤用 chain 導致上下文重置。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved