Spring Boot攔截器(Interceptor)與過濾器(Filter)詳細教程

Spring Boot攔截器(Interceptor)與過濾器(Filter)詳細教程


目錄

  1. 概述
    • 什么是攔截器(Interceptor)?
    • 什么是過濾器(Filter)?
    • 兩者的核心區別
  2. 使用場景
    • 攔截器的典型應用
    • 過濾器的典型應用
  3. 實現步驟
    • 攔截器的創建與配置
    • 過濾器的創建與配置
  4. 代碼示例
    • 自定義攔截器
    • 自定義過濾器
  5. 執行順序與流程
    • 過濾器、攔截器、Controller的執行順序
    • 可視化流程圖
  6. 常見問題與解決方案
  7. 總結

1. 概述

1.1 什么是攔截器(Interceptor)?

攔截器是 Spring MVC 框架的組件,基于 AOP(面向切面編程) 實現。它允許在請求處理的不同階段(如Controller方法執行前后)插入自定義邏輯。

1.2 什么是過濾器(Filter)?

過濾器是 Java Servlet規范 定義的組件,作用于所有進入容器的請求(如Tomcat)。它可以在請求到達Servlet前或響應返回客戶端前進行預處理和后處理。

1.3 核心區別

特性攔截器(Interceptor)過濾器(Filter)
所屬框架Spring MVCServlet API
作用范圍僅Spring MVC管理的請求所有請求(包括靜態資源)
依賴依賴Spring容器依賴Servlet容器(如Tomcat)
執行時機Controller方法前后Servlet處理前后
獲取Bean支持(通過Spring上下文)不支持(需通過其他方式注入)

2. 使用場景

2.1 攔截器的典型應用

  • 日志記錄:記錄請求參數、響應時間。
  • 權限驗證:檢查用戶是否登錄或擁有權限。
  • 事務管理:在Controller方法前后開啟/提交事務。
  • 性能監控:統計接口耗時。

2.2 過濾器的典型應用

  • 全局字符編碼:統一設置請求/響應的編碼(如UTF-8)。
  • 跨域處理:添加CORS響應頭。
  • XSS防御:過濾請求參數中的惡意腳本。
  • 請求壓縮:對響應內容進行GZIP壓縮。

3. 實現步驟

3.1 創建攔截器

步驟:

  1. 實現 HandlerInterceptor 接口,重寫以下方法:
    • preHandle():在Controller方法執行前調用。
    • postHandle():在Controller方法執行后、視圖渲染前調用。
    • afterCompletion():在請求完成后調用(視圖渲染后)。
  2. 注冊攔截器到Spring MVC配置。

代碼示例:

public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 檢查用戶是否登錄if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/login");return false; // 中斷請求}return true;}
}

注冊攔截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/static/**");}
}

注冊多個攔截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 第一個攔截器:日志(優先級高)registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**")       // 攔截所有路徑.excludePathPatterns("/static/**"); // 排除靜態資源// 第二個攔截器:權限(優先級低)registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");  // 僅攔截/api路徑}
}

關鍵配置選項

配置方法說明
addPathPatterns("/api")指定攔截的路徑(支持Ant風格)
excludePathPatterns("/login")排除特定路徑
order(1)顯式設置順序(默認按注冊順序)

若要手動指定順序,可添加:

registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);

3.2 創建過濾器

步驟:

  1. 實現 javax.servlet.Filter 接口,重寫 doFilter 方法。
  2. 注冊過濾器到Servlet容器(通過注解或配置類)。

代碼示例:

@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("請求開始: " + ((HttpServletRequest) request).getRequestURI());chain.doFilter(request, response); // 繼續執行后續過濾器或ServletSystem.out.println("請求結束");}
}

注冊過濾器(若未使用@WebFilter):

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<LoggingFilter> loggingFilter() {FilterRegistrationBean<LoggingFilter> bean = new FilterRegistrationBean<>();bean.setFilter(new LoggingFilter());bean.addUrlPatterns("/*");bean.setOrder(1); // 設置執行順序return bean;}
}

注意: 確保主類添加 @ServletComponentScan 以啟用 @WebFilter 注解。


4. 執行順序與流程

4.1 執行順序

  1. 過濾器(FilterChain) → 2. 攔截器(preHandle) → 3. Controller方法 → 4. 攔截器(postHandle) → 5. 視圖渲染 → 6. 攔截器(afterCompletion) → 7. 過濾器后續處理

4.2 流程圖

客戶端 → Filter.doFilter() → Interceptor.preHandle()→ Controller → Interceptor.postHandle()→ 視圖渲染 → Interceptor.afterCompletion()→ Filter.doFilter()后續處理 → 客戶端

5. 常見問題與解決方案

Q1:如何控制多個攔截器/過濾器的執行順序?

  • 攔截器:通過 registry.addInterceptor() 的順序決定。
  • 過濾器:通過 FilterRegistrationBean.setOrder() 設置優先級(值越小越先執行)。

Q2:攔截器中如何獲取Spring管理的Bean?

直接從Spring容器注入:

public class AuthInterceptor implements HandlerInterceptor {@Autowiredprivate UserService userService; // 直接注入
}

Q3:過濾器中如何修改請求參數?

通過自定義 HttpServletRequestWrapper

public class ModifyRequestWrapper extends HttpServletRequestWrapper {// 重寫getParameter等方法以修改參數
}// 在Filter中替換Request對象
chain.doFilter(new ModifyRequestWrapper(request), response);

Q4:攔截器和過濾器執行時出現異常如何處理?

  • 攔截器:在 afterCompletion 中處理異常。
  • 過濾器:使用 try-catch 包裹 chain.doFilter()

Q5:如何讓某個攔截器全局生效?

使用 addPathPatterns("/**")

registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");

Q6:如何跳過特定攔截器的執行?

preHandle 中返回 false

@Override
public boolean preHandle(...) {if (跳過條件) {return false; // 后續攔截器和Controller不會執行}return true;
}

Q7:攔截器之間如何共享數據?

通過 request.setAttribute 傳遞:

// 在第一個攔截器中存儲數據
request.setAttribute("key", "value");// 在后續攔截器中獲取
String value = (String) request.getAttribute("key");

6. 總結

  • 選擇攔截器還是過濾器?

    • 需要訪問Spring上下文或Controller信息 → 攔截器。
    • 需處理所有請求(包括靜態資源) → 過濾器。
  • 最佳實踐

    • 優先使用攔截器處理業務相關邏輯。
    • 使用過濾器處理底層Servlet容器的任務(如編碼、壓縮)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71193.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71193.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71193.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Tauri跨平臺開發問題及解決方案深度解析(React版)

Tauri跨平臺開發問題及解決方案深度解析&#xff08;React版&#xff09; 一、環境配置與項目初始化難題&#xff08;React適配&#xff09; 1.1 React項目初始化 推薦模板&#xff1a; # 使用ReactTypeScript模板 npm create tauri-applatest -- --template react-ts# 項目…

AIGC和搜索引擎的異同

AIGC&#xff08;生成式人工智能&#xff09;與搜索引擎的核心差異體現在信息處理方式和輸出形態上&#xff0c;我們可以從以下維度對比&#xff1a; 一、工作原理的本質差異 信息檢索機制 搜索引擎&#xff1a;基于關鍵詞匹配&#xff08;如"中暑怎么辦"→返回相關…

SFT與RLHF的關系

在大模型訓練中&#xff0c;SFT&#xff08;監督微調&#xff09;和RLHF&#xff08;基于人類反饋的強化學習&#xff09;是相互關聯但目標不同的兩個階段&#xff0c;通常需要結合使用以優化模型性能&#xff0c;而非互相替代。以下是關鍵要點&#xff1a; 1. 核心關系 SFT&…

C# 類型轉換

C# 類型轉換 引言 在C#編程語言中&#xff0c;類型轉換是一種將一個數據類型的變量轉換成另一個數據類型的操作。類型轉換是編程中常見的操作&#xff0c;特別是在處理不同數據類型的變量時。本文將詳細探討C#中的類型轉換&#xff0c;包括隱式轉換和顯式轉換&#xff0c;以及…

提升系統效能:從流量控制到并發處理的全面解析

在當今快速發展的數字時代&#xff0c;無論是構建高效的網絡服務、管理海量數據&#xff0c;還是優化系統的并發處理能力&#xff0c;都是技術開發者和架構師們面臨的重大挑戰。本文集旨在深入探討幾個關鍵技術領域&#xff0c;包括用于網絡通信中的漏桶算法與令牌桶算法的原理…

Git GitHub基礎

git是什么&#xff1f; Git是一個分布式版本控制系統&#xff0c;用于管理源代碼的變更。它允許多個開發者在同一個項目上協作&#xff0c;同時跟蹤每個修改的歷史記錄。 關鍵詞&#xff1a; 分布式版本控制軟件 軟件 安裝到我們電腦上的一個工具 版本控制 例如論文&…

派可數據BI接入DeepSeek,開啟智能數據分析新紀元

派可數據BI產品完成接入DeepSeek&#xff0c;此次接入標志著派可數據BI在智能數據分析領域邁出了重要一步&#xff0c;將為用戶帶來更智能、更高效、更便捷的數據分析體驗。 派可數據BI作為國內領先的商業智能解決方案提供商&#xff0c;一直致力于為用戶提供高效、穩定易擴展…

Linux-ftrace-雙nop機制的實現

Linux 內核調試工具ftrace 之&#xff08;NOP動態插樁的實現原理&#xff09; ftrace 是 Linux 內核中的一種跟蹤工具&#xff0c;主要用于性能分析、調試和內核代碼的執行跟蹤。它通過在內核代碼的關鍵點插入探針&#xff08;probe&#xff09;來記錄函數調用和執行信息。這對…

Qt互斥鎖(QMutex)的使用、QMutexLocker的使用

Qt互斥鎖【QMutex】的使用、QMutexLocker的使用 基于讀寫鎖(QReadWriteLock)的線程同步Chapter1 Qt互斥鎖(QMutex)的使用、QMutexLocker的使用一、QMutexLocker和QMutex實現示例圖二、QMutex和QMutexLocker的關系&#xff08;個人理解&#xff09;三、QMutex使用和QMutexLocker…

【無標題】Ubuntu22.04編譯視覺十四講slambook2 ch4時fmt庫的報錯

Ubuntu22.04編譯視覺十四講slambook2 ch4時fmt庫的報錯 cmake ..順利&#xff0c;make后出現如下報錯&#xff1a; in function std::make_unsigned<int>::type fmt::v8::detail::to_unsigned<int>(int): trajectoryError.cpp:(.text._ZN3fmt2v86detail11to_unsi…

SpringBoot ——簡單開發流程實戰

本文使用SpringBoot進行電商系統商品數據增刪改查的簡單開發流程。 本文目錄 一、創建Spring Boot項目二、配置數據庫連接三、創建實體類四、創建Repository接口五、創建Service層六、創建Controller層七、測試 一、創建Spring Boot項目 可以通過https://start.spring.io/或者…

fastadmin 后臺商品sku(vue)

先上個效果圖 首先先引入vue define([backend], function (Backend) {require.config({paths: {vue: /assets/jeekshopskugoods/libs/vue.min,skuimg: /assets/jeekshopskugoods/js/skuimg,skugoods: /assets/jeekshopskugoods/js/skugoods,layui: /assets/LayuiSpzj/layui/la…

LeetCode 718 - 最長重復子數組

LeetCode 718 - 最長重復子數組 是一個典型的數組和字符串問題&#xff0c;適合考察動態規劃、滑動窗口和二分查找等多種編程能力。掌握其多種解法及變體能夠有效提高處理字符串和數組算法的能力。 題目描述 輸入: 兩個整數數組 nums1 和 nums2。輸出: 兩個數組中存在的最長的…

LeetCode 0132.分割回文串 II:動態規劃

【LetMeFly】132.分割回文串 II&#xff1a;動態規劃 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/palindrome-partitioning-ii/ 給你一個字符串 s&#xff0c;請你將 s 分割成一些子串&#xff0c;使每個子串都是回文串。 返回符合要求的 最少分割次數 。 示例 …

iOS 實現UIButton自動化點擊埋點

思路&#xff1a;我們HOOK UIControl的 addtarget:action:forControlEvents方法&#xff0c;交換UIControl的 addtarget:action:forControlEvents 方法的實現&#xff0c; 在交換的方法中添加原來響應的同時&#xff0c;再添加一個埋點響應&#xff0c;該響應方法實現了點擊埋點…

C++藍橋杯基礎篇(六)

片頭 嗨~小伙伴們&#xff0c;大家好&#xff01;今天我們來一起學習藍橋杯基礎篇&#xff08;六&#xff09;&#xff0c;練習相關的數組習題&#xff0c;準備好了嗎&#xff1f;咱們開始咯&#xff01; 第1題 數組的左方區域 這道題&#xff0c;實質上是找規律&#xff0c;…

git -學習筆記

目錄 基本操作語法 設置用戶和郵箱 版本回退 工作區和暫存區 撤銷修改 刪除與恢復 一工作區刪除了&#xff0c;但是暫存區沒刪除 二工作區誤刪了&#xff0c;暫存區還有 github-Git 連接 報錯解決-push遠程倉庫被拒絕 遠程庫 分支 分支沖突 儲藏分支 回到當前分…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的電腦本地部署一下DeepSeek試試&#xff0c;由于不希望污染電腦的Windows環境&#xff0c;所以在wsl中安裝了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安裝了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

力扣785. 判斷二分圖

力扣785. 判斷二分圖 題目 題目解析及思路 題目要求將所有節點分成兩部分&#xff0c;每條邊的兩個端點都必須在不同集合中 二分圖&#xff1a;BFS/DFS/并查集 因為圖不一定聯通&#xff0c;所以枚舉所有點都做bfs(如果沒聯通的話) 代碼 class Solution { public:bool is…

springboot之集成Elasticsearch

目錄 二、Elasticsearch 是什么&#xff1f;三、Elasticsearch 安裝四、Springboot 集成 Elasticsearch 的方式五、創建項目集成 Elasticsearch 2.創建 Spring Initializr 項目 es &#xff08;3&#xff09;.新建實體類 User&#xff08;4&#xff09;.新建 dao 接口類 UserR…