Struts2 預設攔截器棧 (`defaultStack`) 滿足大多數場景,但業務常需「權限檢查、日誌記錄、參數預處理」等橫切邏輯。本文詳解自定義攔截器的三種實現方式、兩種註冊粒度與最佳實踐代碼。
| 方式 | 核心類/接口 | 必須實現方法 | 特點 |
|---|---|---|---|
實現 Interceptor 接口 | com.opensymphony.xwork2.interceptor.Interceptor | init(), destroy(), intercept(ActionInvocation) | 最原始、完全控制生命週期 |
繼承 AbstractInterceptor | com.opensymphony.xwork2.interceptor.AbstractInterceptor | intercept(ActionInvocation) | 預設空實現 init/destroy,**推薦** |
繼承 MethodFilterInterceptor | com.opensymphony.xwork2.interceptor.MethodFilterInterceptor | doIntercept(ActionInvocation) | 內建方法名過濾,適合「僅攔截特定 Action 方法」 |
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 會映射到對應
}
}
<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>
<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>
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 必帶、線程安全」五字訣,即可靈活實現橫切關注點分離。