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

Struts 2 攔截器深度解析(一):自定義攔截器、攔截器棧與實戰案例

     編輯:Java 相關知識

前言:攔截器是 Struts 2 的靈魂

Struts 2 採用攔截器鏈實現 AOP(面向切面編程),核心功能(參數封裝、文件上傳、驗證、I18N 等)均由預設攔截器棧 defaultStack 完成。掌握攔截器機制是精通 Struts 2 的關鍵。

核心概念對比

維度Filter (Servlet)Interceptor (Struts 2)
規範層級Servlet 標準框架內部
作用範圍所有請求/響應Action 執行前後
可插拔性web.xml 配置struts.xml 靈活組裝
訪問上下文ServletRequest/ResponseActionInvocation (含 Action、Result)

自定義攔截器開發步驟

1. 實現 Interceptor 接口或繼承 AbstractInterceptor

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

public class InterceptorDemo1 extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("攔截前 Demo1");
        String result = invocation.invoke(); // 放行,執行下一個攔截器或 Action
        System.out.println("攔截後 Demo1");
        return result; // 必須返回 Action 執行結果
    }
}

2. struts.xml 中聲明並引用

<package name="p1" extends="struts-default">
    <interceptors>
        <interceptor name="demo1" class="com.itheima.interceptor.InterceptorDemo1"/>
        <interceptor name="demo2" class="com.itheima.interceptor.InterceptorDemo2"/>
    </interceptors>

    <action name="action1" class="com.itheima.action.Demo1Action" method="execute">
        <interceptor-ref name="demo1"/>
        <interceptor-ref name="demo2"/>
        <result>/success.jsp</result>
    </action>
</package>

3. 關鍵注意點

  • 一旦在 Action 指定 <interceptor-ref>,defaultStack 即失效,需手動引入:<interceptor-ref name="defaultStack"/>
  • 攔截器順序即執行順序:聲明在前的先執行 intercept() 前半段,後執行後半段(棧帳結構)。

攔截器棧:組裝可復用的攔截器鏈

<interceptors>
    <interceptor name="loginCheck" class="com.itheima.interceptor.LoginCheckInterceptor"/>
    <interceptor name="timer" class="com.itheima.interceptor.TimerInterceptor"/>

    <interceptor-stack name="myDefaultStack">
        <interceptor-ref name="defaultStack"/> <!-- 保留框架核心功能 -->
        <interceptor-ref name="loginCheck"/>
        <interceptor-ref name="timer"/>
    </interceptor-stack>
</interceptors>

<default-interceptor-ref name="myDefaultStack"/> <!-- 包級別預設棧 -->

實戰案例一:登錄檢查攔截器

LoginCheckInterceptor.java

public class LoginCheckInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        HttpSession session = ServletActionContext.getRequest().getSession();
        if (session.getAttribute("user") == null) {
            return "login"; // 返回邏輯視圖名,對應 <result name="login">/login.jsp</result>
        }
        return invocation.invoke(); // 已登錄,放行
    }
}

配置要點

<action name="login" class="com.itheima.action.CustomerAction" method="login">
    <result>/login.jsp</result>
</action>
<!-- 其他受保護 Action 引用 myDefaultStack 即可自動攔截 -->

實戰案例二:Action 執行耗時監控

public class TimerInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        long start = System.nanoTime();
        String result = invocation.invoke();
        System.out.println(result + " 耗時:" + (System.nanoTime() - start) + " 納秒");
        return result;
    }
}

MethodFilterInterceptor:精確控制攔截方法

繼承 MethodFilterInterceptor 可通過配置指定只攔截某些方法或排除某些方法:

public class LoginCheckInterceptor extends MethodFilterInterceptor {
    @Override
    protected String doIntercept(ActionInvocation invocation) throws Exception {
        // 核心邏輯同上
    }
}

struts.xml 配置示例

<interceptor name="loginCheck" class="com.itheima.interceptor.LoginCheckInterceptor">
    <param name="excludeMethods">login,register</param> <!-- 登錄/註冊不攔截 -->
</interceptor>
<!-- 或 -->
<param name="includeMethods">add,edit,delete</param> <!-- 僅攔截增刪改 -->

Struts 2 內置核心攔截器速查

  • params:請求參數封裝到 Action 屬性
  • fileUpload:文件上傳處理
  • validation:數據驗證
  • workflow:驗證失敗流程控制
  • i18n:國際化
  • servletConfig:注入 Servlet API
  • prepare:Preparable 接口支持
  • modelDriven:ModelDriven 接口支持

總結

Struts 2 攔截器機制極其靈活:自定義邏輯 → 聲明註冊 → 組裝棧 → 精確應用。實戰中務必記住:引用自定義攔截器時必須顯式包含 defaultStack,否則框架核心功能(參數封裝、文件上傳等)將失效。善用 MethodFilterInterceptor 可避免對登錄、靜態資源等無需攔截的請求造成干擾。

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