首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts Action 轉向機制詳解:五種 Action 組態模式與最佳實踐

     編輯:Java 相關知識

Action 轉向核心流程

Struts 處理請求的標準流程:

  1. ActionServlet 接收請求,依 struts-config.xml 定位 ActionMapping
  2. 依 scope 尋找/建立 ActionForm 實例
  3. 呼叫 form.reset() → 封裝請求參數 → form.validate()(若 validate="true")
  4. 驗證失敗 → 轉向 input 指定 URI;驗證通過 → 呼叫 Action.execute()
  5. 依 ActionForward 轉向目標頁面或 Action

五種經典 Action 組態模式

1. 完整型 Action(標準 MVC)

<action path="/fullAction"
    type="com.example.FullAction"
    name="userForm"
    input="/form.jsp">
    <forward name="success" path="/success.jsp"/>
    <forward name="fail" path="/fail.jsp"/>
</action>
  • 具備 Form 驗證、Action 業務邏輯、多重轉向
  • execute() 僅在驗證通過後執行

2. 僅 Form 型 Action(資料準備轉向)

<action path="/formOnly"
    type="org.apache.struts.actions.ForwardAction"
    name="searchForm"
    input="/search.jsp"
    parameter="/result.jsp"/>
  • 無自訂 Action 類別,使用內建 ForwardAction
  • 邏輯寫在 Form.reset()/validate() 中(存取業務層)
  • 僅能 forward,不可 redirect
  • 適用:查詢條件驗證 → 轉向結果頁

3. 僅 Action 型 Action(連結式請求)

<action path="/actionOnly"
    type="com.example.LogoutAction"
    input="/login.jsp">
    <forward name="success" path="/login.jsp"/>
    <forward name="fail" path="/error.jsp"/>
</action>
  • 無 Form,execute() 自行從 HttpServletRequest 取參數
  • 可 forward 或 redirect
  • 適用:登出、刪除、狀態切換等無表單提交操作

4. 僅 JSP 型 Action(靜態頁面代理)

<action path="/jspOnly"
    type="org.apache.struts.actions.ForwardAction"
    parameter="/static/help.jsp"/>
  • 無 Form、無 Action 邏輯,純轉向
  • 用途:系統參數化頁面路徑、編譯後調整導航無需重編譯

5. 雙 Action 共享單一 Form(命令物件傳遞)

<action path="/step1"
    type="com.example.Step1Action"
    name="wizardForm"
    input="/step1.jsp">
    <forward name="next" path="/step2.do"/>
</action>
<action path="/step2"
    type="com.example.Step2Action"
    name="wizardForm"
    input="/step2.jsp">
    <forward name="success" path="/done.jsp"/>
</action>

關鍵挑戰:Step2 會再次呼叫 form.reset() 和 validate(),可能覆蓋 Step1 存入的資料。

解決方案 A:Request 屬性標記(僅 forward 適用)

// Step1Action.execute()
request.setAttribute("FROM_STEP1", Boolean.TRUE);
return mapping.findForward("next");

// Step2Form.reset()
if (request.getAttribute("FROM_STEP1") != null) return; // 保留資料

解決方案 B:Redirect + Session 標記(解耦合、防重複提交)

<forward name="next" path="/step2.do" redirect="true"/>
// Step1 結束前
session.setAttribute("WIZARD_DATA", form.getData());
session.setAttribute("WIZARD_ACTIVE", Boolean.TRUE);

// Step2 初始化
if (session.getAttribute("WIZARD_ACTIVE") != null) {
    form.setData((Data) session.getAttribute("WIZARD_DATA"));
    session.removeAttribute("WIZARD_ACTIVE");
}

進階模式:分離輸入/輸出 Form

<action path="/step1" ... name="inputForm" ...>
    <forward name="next" path="/step2.do" redirect="true"/>
</action>
<action path="/step2" ... name="outputForm" ...> ... </action>
  • Step1 處理輸入驗證、持久化
  • Redirect 到 Step2
  • Step2 從業務層讀取資料填入 outputForm 顯示
  • 優點:redirect 避免重複提交、降低耦合、分離關注點

轉向類型對比

特性Forward (RequestDispatcher)Redirect (sendRedirect)
瀏覽器網址列不變改變為目標 URL
Request 物件共享重新建立
跨 Context不可可
重複提交風險高(F5 重送)低
適用場景同一流程內步驟流程結束、跨模組、POST 後導向 GET

最佳實踐總結

  1. 表單提交採用 Post-Redirect-Get (PRG) 模式防重複提交
  2. 多步驟精靈使用 Redirect + Session 傳遞命令物件
  3. 業務邏輯集中在 Action,Form 僅負責資料封裝與驗證
  4. 善用 global-forwards 定義共用導航邏輯名稱
  5. 避免在 Form 中放置業務邏輯,維持關注點分離
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved