Spring Boot 攔截器(Interceptor)與過濾器(Filter)有什么區別?

在 Spring Boot 項目中,我們經常會遇到需要在請求處理前后執行一些通用邏輯的場景,比如記錄日志、權限校驗、全局異常處理等。此時,我們通常會面臨兩種選擇:過濾器(Filter)攔截器(Interceptor)

雖然兩者都能實現類似的功能,但它們在實現原理、使用場景、執行時機等方面有著本質的區別。本文將帶你深入剖析這兩者的差異,并通過實戰案例,讓你徹底搞懂何時該用過濾器,何時該用攔截器。

在這里插入圖片描述

一、核心概念:從根上理解它們的區別

1.1 過濾器(Filter)

  • 規范層級:屬于 Java Servlet 規范 的一部分,由 Servlet 容器(如 Tomcat)直接管理。
  • 作用范圍:對整個 Web 應用生效,包括靜態資源(如 HTML、CSS、JS 等)。
  • 觸發時機:在請求進入 DispatcherServlet 之前,以及響應返回客戶端之后。
  • 依賴關系:不依賴 Spring 容器,可以脫離 Spring 獨立使用。

1.2 攔截器(Interceptor)

  • 規范層級:Spring MVC 框架提供的機制,由 Spring 容器管理。
  • 作用范圍:僅對 Spring MVC 控制器(Controller) 的請求生效,默認不攔截靜態資源。
  • 觸發時機:在請求進入 DispatcherServlet 之后,到達 Controller 之前,以及 Controller 處理完請求之后。
  • 依賴關系:深度集成 Spring 容器,可以方便地使用 Spring 的依賴注入(DI)和 AOP 功能。
特性對比過濾器(Filter)攔截器(Interceptor)
規范層級Java Servlet 規范Spring MVC 框架
作用范圍所有請求(包括靜態資源)僅 Controller 請求
觸發時機DispatcherServlet 前后Controller 前后
依賴容器Servlet 容器Spring 容器
能否修改請求/響應可以直接修改不能直接修改,但可操作 Model 和 View

二、執行流程:一個圖看懂它們的調用順序

為了更直觀地理解兩者的執行順序,我們來看一張經典的流程圖:

HTTP Request↓
Filter Chain(doFilter)↓
DispatcherServlet↓
Interceptor.preHandle↓
Controller Method↓
Interceptor.postHandle↓
View Rendering(如有)↓
Interceptor.afterCompletion↓
Filter Chain(返回響應)

從這個流程可以看出:

  • 過濾器 是最外層的“大門”,所有請求都必須經過它。
  • 攔截器 是內層的“小門”,只對進入 Spring MVC 的請求生效。

三、實戰演練:代碼說話最真實

3.1 過濾器(Filter)實戰:記錄請求耗時

@Component
public class LogFilter implements Filter {private static final Logger logger = LoggerFactory.getLogger(LogFilter.class);@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {long startTime = System.currentTimeMillis();HttpServletRequest httpRequest = (HttpServletRequest) request;logger.info("請求開始,URI: {}", httpRequest.getRequestURI());chain.doFilter(request, response); // 放行請求long duration = System.currentTimeMillis() - startTime;logger.info("請求結束,耗時: {}ms", duration);}
}

3.2 攔截器(Interceptor)實戰:登錄權限校驗

@Component
public class AuthInterceptor implements HandlerInterceptor {@Autowiredprivate AuthService authService; // 可以注入Spring Bean@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if (!authService.isValidToken(token)) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false; // 攔截請求}return true; // 放行請求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {logger.info("Controller 方法執行完畢,準備渲染視圖");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {logger.info("請求處理完成,資源清理");}
}

3.3 配置攔截器到Spring容器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Autowiredprivate AuthInterceptor authInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor).addPathPatterns("/api/**") // 攔截所有 /api 開頭的請求.excludePathPatterns("/api/login"); // 排除登錄接口}
}

四、選型指南:什么時候用過濾器,什么時候用攔截器?

場景需求推薦方案
需要處理靜態資源(如HTML、CSS、JS)過濾器(Filter)
需要最早攔截請求(如全局跨域處理)過濾器(Filter)
需要訪問Spring Bean(如Service、Repository)攔截器(Interceptor)
需要精確控制Controller方法的執行前后攔截器(Interceptor)
需要修改請求和響應的內容(如壓縮、編碼)過濾器(Filter)

五、常見誤區與最佳實踐

5.1 常見誤區

  • 誤區1:攔截器可以處理靜態資源
    實際上,攔截器默認不會攔截靜態資源,除非你手動配置了 addResourceHandler

  • 誤區2:過濾器可以直接使用Spring Bean
    過濾器由Servlet容器管理,默認無法使用Spring的依賴注入。可以通過 DelegatingFilterProxy 橋接,但配置較復雜。

  • 誤區3:攔截器可以修改請求參數
    攔截器無法直接修改請求參數,如需修改,需使用過濾器配合 HttpServletRequestWrapper

5.2 最佳實踐

  • 優先使用攔截器:除非必須處理靜態資源或需要最早攔截,否則優先使用攔截器,因為它更貼近業務邏輯,且易于測試。
  • 避免復雜邏輯:無論是過濾器還是攔截器,都應避免復雜的業務邏輯,以免影響性能。
  • 合理配置順序:如果同時使用多個過濾器或攔截器,務必注意它們的執行順序,避免邏輯沖突。

六、總結:一句話記住它們的區別

過濾器(Filter)是 Servlet 的“大門”,攔截器(Interceptor)是 Spring MVC 的“小門”。

  • Filter:更早、更底層、更通用,但離業務邏輯較遠。
  • Interceptor:更晚、更上層、更靈活,更貼近業務邏輯。

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

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

相關文章

【技術教程】如何將文檔編輯器集成至基于Java的Web應用程序

在如今的企業協作場景中,“文檔” 早已不是簡單的文字載體!從項目需求文檔的多人實時修改,到財務報表的在線批注,再到合同草案的版本追溯,用戶越來越需要在 Web 應用內直接完成 “編輯 - 協作 - 存儲” 全流程。 但很…

多模態大模型Keye-VL-1.5發布!視頻理解能力更強!

近日,快手正式發布了多模態大語言模型Keye-VL-1.5-8B。 與之前的版本相比,Keye-VL-1.5的綜合性能實現顯著提升,尤其在基礎視覺理解能力方面,包括視覺元素識別、推理能力以及對時序信息的理—表現尤為突出。Keye-VL-1.5在同等規模…

洗完頭后根據個人需求選擇合適的自然風干 | 電吹風 (在保護發質的同時,也能兼顧到生活的便利和舒適。)

文章目錄 引言 I 選合適的方式讓頭發變干 時間充裕,不需要做造型,選擇自然風干 使用電吹風,比較推薦的做法 II 自然風干 天冷可能刺激頭皮 III 電吹風吹干 容易造型 影響頭皮健康 損傷發質 科普 頭皮的微觀結構 頭發絲 引言 吹風吹干:容易造型,但損傷發質、影響頭皮健康 …

GPS汽車限速器有哪些功能?主要運用在哪里?

GPS 汽車限速器是一種結合全球衛星定位(GPS)技術、車速采集技術與車輛控制 / 預警邏輯的設備,核心目標是通過技術手段限制車輛行駛速度,減少超速引發的交通事故,并輔助車輛管理。其功能與應用場景高度匹配不同用戶的 “…

Python從入門到精通_01_python基礎

1 源代碼格式在python文件的第一行,輸入以下語句,可以將python文件的編碼格式設置為utf-8#-*- coding:utf-8 -*-2 輸入輸出input():輸入,無論輸入的是什么類型數據,最后都是字符串類型print(*args, sep , end\n, fileNone, flushF…

使用CI/CD部署項目(前端Nextjs)

寫在前面:在github上使用CI/CD部署Nextjs項目,具體配置可以按照自己的實際的修改 這是我的項目配置,僅供參考 后端項目可以參考:使用CI/CD部署后端項目 正文開始 項目名(PROJECT_NAME)- CI/CD 部署指南…

Java全棧工程師面試實錄:從基礎到實戰的全面解析

Java全棧工程師面試實錄:從基礎到實戰的全面解析 面試官:李明(資深技術負責人) 應聘者:張宇(28歲,碩士學歷,5年開發經驗) 第一輪:Java語言與JVM基礎 李明&…

C#中解析XML時遇到注釋節點報錯

在C#中解析XML時遇到注釋節點報錯的問題&#xff0c;這是因為XML注釋節點&#xff08;<!-- -->&#xff09;是特殊的節點類型。當遍歷XML節點時&#xff0c;注釋節點也會被包含在內&#xff0c;但它們不能像普通元素節點那樣處理。 解決方案 方法1&#xff1a;跳過注釋節…

9.3深度循環神經網絡

目前為止&#xff0c;只討論了具有一個單向隱藏層的循環神經網絡&#xff0c;其中隱變量和觀測值域具體的函數形式的交互方式是相當隨意的。只要交互類型建模具有足夠的靈活性&#xff0c;不是一個單問題。然而&#xff0c;對一個單層來說&#xff0c;可能具有相當的挑戰性。之…

CSS in JS 的演進:Styled Components, Emotion 等的深度對比與技術選型指引

CSS in JS 的演進&#xff1a;Styled Components, Emotion 等的深度對比與技術選型指引在現代前端開發中&#xff0c;組件化思維已成為主流&#xff0c;而如何科學、高效地管理組件的樣式&#xff0c;也隨之成為了一個重要議題。CSS in JS&#xff08;JS中的CSS&#xff09;應運…

【正則表達式】 正則表達式的分組和引用

?? 個人主頁:(時光煮雨) ?? 高質量專欄:vulnhub靶機滲透測試 ?? 希望得到您的訂閱和支持~ ?? 創作高質量博文(平均質量分95+),分享更多關于網絡安全、Python領域的優質內容!(希望得到您的關注~) ??目錄?? 前言 ??一、基本語法 ??二、分組類型 ??2.1.…

Grafana 導入儀表盤失敗:從日志排查到解決 max\_allowed\_packet 問題

問題背景 近期在為項目搭建一套基于 Prometheus 和 Grafana 的可觀測性體系。在完成基礎部署后&#xff0c;我準備導入一個功能相對復雜的官方儀表盤模板&#xff0c;以便快速監控各項指標。然而&#xff0c;當上傳儀表盤的 JSON 文件并點擊保存時&#xff0c;Grafana 界面卻反…

java對接物聯網設備(一)——使用okhttp網絡工具框架對接標準API接口

當前無論是在互聯網領域&#xff0c;還是物聯網項目下&#xff0c;亦或者各類應用類軟件&#xff0c;基于http標準接口的對接是目前市面上最常見也是最簡單的數據交互方式之一&#xff0c;甚至可以說是最流行的&#xff0c;因為它不依賴的各種插件或者服務。 開發者或者提供服…

版本管理系統與平臺(權威資料核對、深入解析、行業選型與國產平臺補充)

本文是一篇基于公開權威資料&#xff08;官方文檔、產品頁、廠商技術文章與技術社區討論&#xff09;重新檢索、核對后撰寫的詳盡博文。內容覆蓋&#xff1a;版本控制基礎、主流 VCS 工具深度比較、常見托管/協作平臺&#xff08;含中國本土平臺&#xff1a;Gitee / GitCode / …

計算機畢設選題:基于Python+Django的B站數據分析系統的設計與實現【源碼+文檔+調試】

精彩專欄推薦訂閱&#xff1a;在 下方專欄&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主頁&#xff1a;計算機畢設木哥&#x1f525; &#x1f496; 文章目錄 一、項目介紹二…

Easy ES技術詳解

從Java代碼示例到高級特性 框架介紹 Easy-Es 是一款以 “簡化 Elasticsearch 操作的 ORM 框架” 為核心定位的開源工具&#xff0c;旨在通過低代碼設計降低 Elasticsearch 的使用門檻。作為國內 Top1 Elasticsearch 搜索引擎框架&#xff0c;其最顯著的優勢在于大幅縮減代碼量…

【51單片機】【protues仿真】基于51單片機停車場的車位管理系統

目錄 一、主要功能 二、使用步驟 三、硬件資源 四、軟件設計 五、實驗現象 一、主要功能 1、LCD1602液晶顯示 2、統計并顯示停車場現有車輛數和已停放過車輛數 3、按鍵設置總車位數以及剩余車位數 4、統計并顯示累計駛入和累計駛出車輛數 5、用16個LED燈模擬停車位 6、車…

【Python】S1 基礎篇 P4 if 語句指南

目錄簡單示例條件測試檢查是否相等與不等檢查多個條件檢查特定的值是否在/不在列表中布爾表達式if語句簡單的if語句if-else語句if-elif-else語句使用if語句處理列表檢查特殊元素確定列表非空使用多個列表總結if 語句是Python編程中最基本也是最重要的控制結構之一。它允許程序根…

【實戰中提升自己】內網安全部署之STP的安全技術部署

1 1拓撲 「模擬器、工具合集」復制整段內容 鏈接&#xff1a;https://docs.qq.com/sheet/DV0xxTmFDRFVoY1dQ?tab7ulgil1 STP的安全技術部署 說明&#xff1a;為什么需要注意STP的安全呢&#xff0c;在二層中其實存在很多不安全的因素&#xff0c;物理上…

GEM5學習(5): ARM 架構功耗仿真

運行腳本基于gem5提供的腳本&#xff0c;啟動功耗仿真。實際工作中應該不會用gem5進行功耗的仿真吧&#xff0c;Cadence和Synopsys好像都有配套的的功耗建模工具。事先要配置好 IMG_ROOT的環境變量./build/ARM/gem5.opt configs/example/arm/fs_power.py \--caches \--bootl…