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

Struts2 自定義攔截器開發指南:從接口實現到包級/Action級註冊全流程

     編輯:Java 綜合教學

前言

Struts2 預設攔截器棧 (`defaultStack`) 滿足大多數場景,但業務常需「權限檢查、日誌記錄、參數預處理」等橫切邏輯。本文詳解自定義攔截器的三種實現方式、兩種註冊粒度與最佳實踐代碼。

一、自定義攔截器三種實現途徑

方式核心類/接口必須實現方法特點
實現 Interceptor 接口com.opensymphony.xwork2.interceptor.Interceptorinit(), destroy(), intercept(ActionInvocation)最原始、完全控制生命週期
繼承 AbstractInterceptorcom.opensymphony.xwork2.interceptor.AbstractInterceptorintercept(ActionInvocation)預設空實現 init/destroy,**推薦**
繼承 MethodFilterInterceptorcom.opensymphony.xwork2.interceptor.MethodFilterInterceptordoIntercept(ActionInvocation)內建方法名過濾,適合「僅攔截特定 Action 方法」

二、核心代碼範例(繼承 AbstractInterceptor)

package com.nucsoft.struts.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        // 1. 前置邏輯:如檢查登錄、記錄請求參數
        System.out.println("【MyInterceptor】pre-handle: " + invocation.getAction().getClass().getSimpleName());
        
        // 2. 執行後續攔截器鏈 + Action
        String result = invocation.invoke();
        
        // 3. 後置邏輯:如記錄響應時間、統一異常處理
        System.out.println("【MyInterceptor】post-handle, result=" + result);
        return result; // 直接返回結果碼,Struts 會映射到對應 
    }
}

三、註冊與使用:兩種粒度

1. Action 級註冊(精準控制)

<package name="default" namespace="/" extends="struts-default">
    <!-- 定義攔截器 -->
    <interceptor name="myInterceptor" class="com.nucsoft.struts.interceptor.MyInterceptor"/>
    
    <action name="interceptor" class="com.nucsoft.struts.token.InterceptorAction">
        <!-- 僅此 Action 使用 -->
        <interceptor-ref name="myInterceptor"/>
        <!-- 必須手動引入 defaultStack,否則失去 params、validation 等預設功能 -->
        <interceptor-ref name="defaultStack"/>
        <result>/success.jsp</result>
        <result name="input">/error.jsp</result>
    </action>
</package>

2. Package 級註冊(全局生效)

<package name="default" namespace="/" extends="struts-default">
    <interceptors>
        <interceptor name="myInterceptor" class="com.nucsoft.struts.interceptor.MyInterceptor"/>
        <!-- 組合成新棧 -->
        <interceptor-stack name="myInterceptorStack">
            <interceptor-ref name="myInterceptor"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    
    <!-- 設為包默認棧 -->
    <default-interceptor-ref name="myInterceptorStack"/>
    
    <action name="myInterceptor" class="com.nucsoft.struts.token.InterceptorAction" method="myInterceptor">
        <result>/success.jsp</result>
        <result name="input">/error.jsp</result>
    </action>
</package>

四、關鍵注意點

  1. 攔截器順序即執行順序:`` 寫在前 = 先執行。`defaultStack` 內部順序為:`servletConfig → prepare → checkbox → params → conversionError → validation → workflow`。
  2. 必須包含 defaultStack:自定義攔截器通常作為**增強**,不能替換核心參數注入、驗證等功能。
  3. 返回 result 碼直接跳轉:`intercept()` 返回字串會短路後續鏈,直接走對應 ``,慎用。
  4. 線程安全:攔截器實例為單例,**不可**在類中定義非線程安全字段(如 `private int count`),請用 `ThreadLocal` 或放入 `ActionContext`。

五、進階:MethodFilterInterceptor 實戰

public class LoginCheckInterceptor extends MethodFilterInterceptor {
    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {
        HttpSession session = ServletActionContext.getRequest().getSession();
        if (session.getAttribute("user") == null) return "login"; // 未登錄跳轉
        return invocation.invoke();
    }
}

配置時指定 `login,register` 自動跳過登錄/註冊方法。

總結

自定義攔截器 = **實現接口/繼承抽象類 + 註冊到 struts.xml + 組合進攔截器棧**。掌握「Action 級精準、Package 級全局、defaultStack 必帶、線程安全」五字訣,即可靈活實現橫切關注點分離。

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