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

Struts2 Alias 攔截器實戰:Action 間參數傳遞與鏈式處理模式

     編輯:Java 綜合教學

Struts2 Alias 攔截器實戰:Action 間參數傳遞與鏈式處理模式

在 Struts2 應用開發中,Action 鏈 是實現「伺服端轉發」並共享請求資料的核心機制。alias 攔截器專門解決「來源 Action 欄位名稱與目標 Action 欄位名稱不一致」的參數映射問題。本文詳細解析其配置原理、實戰用法與常見陷阱。

Chain Result vs Redirect Action 差異

特性Chain Result (type="chain")Redirect Action (type="redirectAction")
轉發位置伺服端 (同一請求)客戶端 (HTTP 302 新請求)
請求物件共享同一 HttpServletRequest新請求,原請求屬性丟失
參數傳遞自動攜帶所有請求參數 + ValueStack需顯式 <param> 或 Session
URL 變化瀏覽器網址列**不變**瀏覽器網址列**更新**為目標 Action
適用場景多步驟表單、工作流、權限檢查後轉發POST-Redirect-GET 模式、防止重複提交

Alias 攔截器核心作用

當使用 Chain Result 時,目標 Action 透過 alias 攔截器接收參數。其核心功能:將來源參數名稱按映射規則重新命名,注入目標 Action 的對應屬性。

完整配置範例

1. web.xml 註冊 Struts2 核心過濾器


<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. struts.xml 定義 Action 鏈與 Alias 映射


<package name="default" extends="struts-default">
    <!-- 來源 Action -->
    <action name="submitOrder" class="com.example.order.SubmitOrderAction">
        <result name="success">/confirm.jsp</result>
        <result name="input" type="chain">
            <param name="actionName">processPayment</param>
        </result>
    </action>

    <!-- 目標 Action:使用 alias 攔截器映射參數 -->
    <action name="processPayment" class="com.example.order.ProcessPaymentAction">
        <!-- 關鍵配置:aliases 參數定義名稱映射 -->
        <param name="aliases">#{'orderId':'paymentOrderId', 'customerName':'payerName', 'amount':'payAmount'}</param>
        <result name="success">/paymentResult.jsp</result>
        <result name="input">/paymentForm.jsp</result>
    </action>
</package>

3. 來源 Action 類別


package com.example.order;

public class SubmitOrderAction extends ActionSupport {
    private String orderId;
    private String customerName;
    private BigDecimal amount;
    // getter/setter 省略

    public String execute() {
        // 業務邏輯驗證
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            addFieldError("amount", "金額必須大於零");
            return INPUT;  // 觸發 chain 到 processPayment
        }
        return SUCCESS;
    }
}

4. 目標 Action 類別


package com.example.order;

public class ProcessPaymentAction extends ActionSupport {
    // 屬性名稱與 aliases 映射的目標名稱一致
    private String paymentOrderId;
    private String payerName;
    private BigDecimal payAmount;
    // getter/setter **必須存在**,否則無法注入

    public String execute() {
        // 此時 paymentOrderId、payerName、payAmount 已自動注入
        // 呼叫支付閘道...
        return SUCCESS;
    }
}

Alias 映射語法詳解


<param name="aliases">#{'sourceParam1':'targetProp1', 'sourceParam2':'targetProp2'}</param>
  • 格式:#{ '來源參數名' : '目標屬性名', ... } (OGNL Map 語法)
  • 來源參數名 = HTTP 請求參數名 / 來源 Action 的屬性名 (經 ValueStack 暴露)
  • 目標屬性名 = 目標 Action 的 JavaBean 屬性名 (需有 setter)
  • 多組映射以逗號分隔

執行流程時序圖


用戶提交表單 → SubmitOrderAction.execute() → 返回 "input"
                    ↓
            ChainResult 執行
                    ↓
            目標 Action (processPayment) 被調用
                    ↓
            AliasInterceptor.intercept() 執行
                    ↓
            遍歷 aliases Map:
                從 ValueStack/請求獲取 sourceParam 值
                呼叫 targetAction.setTargetProp(value)
                    ↓
            目標 Action.execute() 執行 (屬性已注入)

關鍵限制與最佳實踐

限制/陷阱說明對策
目標屬性**必須有 setter**Ognl 需呼叫 setXxx() 注入值確保所有映射目標屬性提供 public setter
來源參數**必須在 ValueStack 或請求中**Chain Result 會將來源 Action 實例壓入 ValueStack來源 Action 屬性需有 getter,或手動 request.setAttribute()
類型轉換自動進行Struts2 類型轉換器處理 String → 目標類型複雜類型註冊自定義 TypeConverter
避免循環鏈A→B→A 導致無限遞迴設計單向流程,或用 redirectAction 打破
Chain Result 不改變 URL用戶重新整理會重送原請求適合「單次提交、多步處理」;不適合「結果頁」

進階用法:動態別名與通配符


<!-- 支援 OGNL 運算式動態決定映射 -->
<param name="aliases">#{'user_*': 'profile_*'}</param>
<!-- 注:Struts2 核心 alias 攔截器不直接支援通配符,需擴展 AliasInterceptor 或使用 ActionMapper -->

替代方案對比

  1. Session 傳遞:session.put("key", val) → 耦合 Session、併發風險、需手動清理
  2. RedirectAction + 參數:<param name="orderId">%{orderId}</param> → URL 暴露參數、長度限制、GET 語義
  3. ValueStack 直接存取:目標 Action 中 ActionContext.getContext().getValueStack().findValue("orderId") → 程式碼耦合框架內部
  4. Alias 攔截器:推薦 — 宣告式、解耦、類型安全、可測試

結語

alias 攔截器是 Struts2 「伺服端轉發 + 參數重命名」的標準解決方案。掌握 Chain Result、ValueStack、JavaBean 慣例 三者交互機制,能優雅實現多步驟業務流程、權限攔截轉發、表單預填等場景。現代專案若遷移至 Spring MVC,對應機制為 @ModelAttribute + forward: 前綴或 HandlerInterceptor 手動映射。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved