攔截器和過濾器(理論+實操)

攔截器和過濾器

本文旨在夯實基礎以及實戰加深理解,目的是更深的理解以便掌握,希望能跟著動手敲一遍,絕對受益匪淺

在本文,我會先給出兩者的區別(理論知識),隨后是兩者各自的實操實現

文章目錄

  • 攔截器和過濾器
    • 什么是過濾器和攔截器?
      • 1.過濾器
      • 2.攔截器
      • 執行整體流程
    • 攔截器和過濾器的區別
  • 實操:
      • 1.過濾器
        • 1.定義日志記錄過濾器類`LogFilter`
        • 2.在主啟動類上**添加注解**`@ServletComponentScan`
      • 2.攔截器
        • 1.創建攔截器
        • 2.注冊攔截器
        • 測試
    • 好了,你學會沒?

什么是過濾器和攔截器?

1.過濾器

首先說下什么是過濾器?

  1. Java Servlet規范中定義的標準,是Servlet一部分,
  2. 配置也是非常簡單,直接實現javax.servlet.Filter接口就可以,
  3. 也可以用注解@WebFilter對特定的URL攔截

2.攔截器

那攔截器又是什么東東?

  1. Spring框架自身提供的組件,也就是說必須依賴SpringMvc框架才能使用,是位于Spring上下文之中
  2. AOP的一種實現,支持鏈式調用,通過類HandlerInterceptor實現多個攔截
  3. 說白了:就是切面編程典型實現,允許程序猿在一些核心業務操作執行的前后插入自定義的邏輯代碼,如日志記錄,權限認證等,而無需修改核心代碼的本身

執行整體流程

我們首先看下過濾器和攔截器在整個流程中的執行順序

請求進入
preHandle
調用Controller
返回ModelAndView
postHandle/afterCompletion
返回響應
響應返回
HTTP Request
Tomcat 容器
Filter 鏈
DispatcherServlet
Interceptor 鏈
Controller
HTTP Response

解釋說明:(結合上圖)

  1. Filter 開始HTTP 請求進入 Tomcat 容器。
  2. Filter 鏈處理:請求會經過所有配置的 FilterdoFilter() 方法。
  3. 進入 Spring MVC:請求到達 DispatcherServlet(Spring MVC 的核心控制器)。
  4. Interceptor 開始DispatcherServlet 分發請求前,會先執行攔截器鏈的 preHandle 方法。
  5. Controller 執行:如果 preHandle 返回 true,請求被分發到對應的 Controller 方法執行。
  6. Interceptor 后處理
    • Controller 執行完畢后,返回 ModelAndView,然后執行攔截器鏈的 postHandle 方法。
    • 視圖渲染完畢后(或請求處理完成后),執行攔截器鏈的 afterCompletion 方法。
  7. Filter 結束:響應最終再次經過 Filter 鏈的 doFilter() 方法(反向),返回給客戶端。

攔截器和過濾器的區別

特性過濾器 (Filter)攔截器 (Interceptor)
歸屬與依賴Servlet 規范,不依賴 SpringSpring 框架 的組件
作用范圍作用于所有進入容器的請求(包括靜態資源,如 /css/, /js/只作用于 Spring MVC 處理的請求(即 Controller 的請求,通常不會攔截靜態資源)
實現原理基于 函數回調 (doFilter())基于 Java 反射和動態代理
使用方式web.xml 中配置或使用 @WebFilter 注解在 Spring MVC 配置中注冊 (WebMvcConfigurer)
獲取 IOC 容器無法 直接獲取 Spring 的 IOC 容器和其中的 Bean可以,因為它本身就是 Spring 管理的,可以輕松使用 @Autowired 注入其他 Bean
執行時機/位置最早。 1. 在請求進入 Tomcat 等容器之后 2. 在進入 Servlet 之前 3. 在 Servlet 處理完之后,返回給客戶端之前較晚。 1. 在請求進入 DispatcherServlet 之后 2. 在進入 Controller 之前 (preHandle) 3. 在 Controller 執行之后,視圖渲染之前 (postHandle) 4. 在整個請求結束之后 (afterCompletion)
功能側重更底層,關注的是請求本身(Request/Response),功能強大。 例如:字符編碼設置、權限校驗(粗粒度)、日志記錄、性能監控、解壓/gzip壓縮。更上層,關注的是 Controller 的方法執行,與業務結合更緊密。 例如:更精細的權限校驗(判斷Token、角色)、日志記錄(記錄Controller方法、參數)、參數預處理、Controller 執行時間計算。

實操:

1.過濾器

案例:Springboot中實現日志記錄過濾器

1.定義日志記錄過濾器類LogFilter

主要的三大核心方法:(可以結合上面的整體執行流程圖來看)

  • init() :該方法在容器啟動初始化過濾器時被調用,在 Filter 的整個生命周期只會被調用一次注意:這個方法必須執行成功,否則過濾器不生效,沒有作用。
  • doFilter() :容器中的每一次請求都會調用該方法, FilterChain 用來調用下一個過濾器 Filter
  • destroy(): 當容器銷毀 過濾器實例時調用該方法,一般在方法中銷毀或關閉資源,在過濾器 Filter 的整個生命周期也只會被調用一次
package com.zhengqian.test01aop.filter;import lombok.extern.slf4j.Slf4j;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*** 日志過濾器: * @author zhengqian* @since 2025年09月04日 14:56*/
@WebFilter(urlPatterns = "/*")//過濾所有的請求
@Slf4j
public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);//初始化執行log.info("***^^^日志過濾器初始化完成");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//記錄請求的開始時間long startTime = System.currentTimeMillis();//轉換為HttpServletRequest獲取更多信息HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;//獲取基本信息String requestURI = httpServletRequest.getRequestURI();String method = httpServletRequest.getMethod();String remoteAddr = httpServletRequest.getRemoteAddr();//log.info("請求開始=> 方法:{} 路徑: {}} IP:{}",method,requestURI,remoteAddr);try {filterChain.doFilter(servletRequest,servletResponse);} finally {//計算處理耗時long duration = System.currentTimeMillis() - startTime;//響應日志log.info("請求結束 ==> 路徑: {} 耗時:{}",requestURI,duration);}}@Overridepublic void destroy() {Filter.super.destroy();log.info("日志過濾器銷毀");}
}
2.在主啟動類上添加注解@ServletComponentScan

在這里插入圖片描述

OK!這個時候你啟動就可以看到此過濾器成功!

你可能會問?這么簡單?對的,就是這么簡單!前提你要跟著做!哈哈哈!

在這里插入圖片描述

2.攔截器

1.創建攔截器

核心方法解釋:

  • preHandle()
    • 此方法在請求處理之前進行調用。
    • 注意:如果該方法的返回值為false ,將視為當前請求結束,不僅自身攔截器會失效,還會導致其他的攔截器也不再執行
  • postHandle()
    • 只有在 preHandle() 方法返回值為true才會執行
    • 會在Controller 中的方法調用之后,DispatcherServlet 返回渲染視圖之前被調用。
  • afterCompletion():只有在 preHandle() 方法返回值為true 時才會執行。在整個請求結束之后, DispatcherServlet 渲染了對應的視圖之后執行。
package com.zhengqian.test01aop.interceptor;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器的實現* @author zhengqian* @since 2025年09月04日 15:13*/
@Slf4j
public class CustomInterceptor implements HandlerInterceptor {/*** 請求處理前被調用* @param request 請求* @param response 響應* @param handler 處理器* @return  aa* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//添加校驗權限log.info("開始出發攔截器校驗前的處理------------->");return true;}/*** **其中**:`postHandle()` 方法被調用的順序跟 `preHandle()` 是**相反**的,先聲明的攔截器  `preHandle()` 方法先執行,而`postHandle()`方法反而會后執行。* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("只有在 preHandle() 方法返回值為true 時才會執行");HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("整個請求結束之后被調用");HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}}
2.注冊攔截器

addPathPatterns:需要攔截的路徑

excludePathPatterns: 不需要攔截的路徑

package com.zhengqian.test01aop.config;import com.zhengqian.test01aop.interceptor.CustomInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author zhengqian* @since 2025年09月04日 15:19*/
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注冊攔截器并設置攔截路徑registry.addInterceptor(new CustomInterceptor())//攔截所有.addPathPatterns("/**")//排除*/login的登錄路徑.excludePathPatterns("/aop/login");}
}
測試

我們建一個測試類,來進行上面的攔截測試

package com.zhengqian.test01aop.controller;import com.zhengqian.test01aop.service.TestService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** @author zhengqian* @date 2025年07月21日 16:40*/
@RestController
@RequestMapping("/aop")
public class TestController {@ResourceTestService testService;@GetMapping("/test")public  String test(){testService.test();return "測試成功!----";}@GetMapping("/login")public  String login(){testService.test();return "測試成功!----";}
}

打印日志:

1.走攔截器

在這里插入圖片描述
在這里插入圖片描述

好了,你學會沒?

在這里插入圖片描述

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

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

相關文章

HTB 賽季8靶場 - Guardian

各位好,最近我的kali崩掉了,崩掉了,建議大家避K 番茄C盤瘦身,這家伙修改了我的avrt.dll文件,導致virtualbox不接受我的avrt.dll文件的簽名了,從而導致virtualbox的虛擬機環境全崩無法開機。弄了幾天&#x…

Rust+slint實現一個登錄demo

系列文章目錄 文章目錄系列文章目錄前言一、為什么前端選擇slint而不是Tauri或者其他GUI框架二、開發工具三、代碼編寫項目結構前端代碼編寫后端開發編寫運行效果總結前言 本文章就是一個簡單rust全棧編程的一個小小的示例供rust新手閱讀學習。 一、為什么前端選擇slint而不是…

2025前端面試題及答案(詳細)

HTML5 的新特性有哪些?簡約版本:“HTML5 新特性主要體現在六個方面: 第一,語義化標簽,比如 header、footer、nav 等,讓頁面結構更清晰; 第二,表單增強,新增了 date、emai…

分詞器詳解(二)

🔍 第2層:中等深度(15分鐘理解) 1. 理論基礎 1.1 BPE的數學原理 核心思想:通過迭代合并高頻字符對構建詞匯表 算法形式化: 初始化詞匯表 V0{c1,c2,...,cn}V_0 \{c_1, c_2, ..., c_n\}V0?{c1?,c2?,...,c…

嵌入式學習 51單片機(3)

UART 概述通用異步收發器(UART)是一種全雙工、串行、異步通信協議,常用于設備間數據傳輸。包含兩根信號線:RXD(接收信號線)TXD(發送信號線)通信方式單工通信方向固定,僅支…

Redis AOF 持久化:銀行的 “交易流水單” 管理邏輯

目錄 一、AOF 的核心邏輯:“每筆交易都記流水” 二、AOF 的三個步驟:從 “臨時記錄” 到 “正式歸檔” 1. 命令追加:記到 “臨時小本本” 2. 寫入與同步:抄到 “正式流水冊” 3. AOF 還原:拿 “流水冊” 重放交易…

代碼隨想錄訓練營第三十天|LeetCode452.用最少數量的箭引爆氣球、LeetCode435.無重疊空間、LeetCode763.劃分字母空間

452.用最少數量的箭引爆氣球 貪心算法 重合最多的氣球射一箭,就是局部用箭數量最少的,全局的用箭數量就是最少的。 首先對二維數組進行排序,這樣就可以讓氣球更加緊湊。 思路:當前氣球是否和上一個氣球區間重合,如…

數據庫事務隔離級別與 MVCC 機制詳解

最近在準備面試,正把平時積累的筆記、項目中遇到的問題與解決方案、對核心原理的理解,以及高頻業務場景的應對策略系統梳理一遍,既能加深記憶,也能讓知識體系更扎實,供大家參考,歡迎討論。在數據庫并發操作…

【Cursor-Gpt-5-high】StackCube-v1 任務訓練結果不穩定性的分析

1. Prompt 我是機器人RL方向的博士生正在學習ManiSkill,在學習時我嘗試使用相同命令訓練同一個任務,但是我發現最終的 success_once 指標并不是相同的,我感到十分焦慮, 我使用的命令如下: python sac.py --env_id"…

文檔權限設置不合理會帶來哪些問題

文檔權限設置不合理會導致信息泄露、合規風險、協作效率下降、責任難以追溯、知識資產流失、員工信任受損、管理成本增加、企業戰略受阻。這些問題不僅影響日常運營,更會對企業的長遠發展構成威脅。根據IBM《2024數據泄露成本報告》,全球企業因數據泄露的…

Linux網絡服務——基礎設置

網絡服務命令1.ping命令作用:測試網絡連通性(使用icmp協議)常見選項:-c:指定ping的次數,默認無限次-I:指定發送請求的網卡[rootlocalhost ~]# ping 192.168.77.78 -c 4 -I ens160 PING 192.168.…

【multisim汽車尾燈設計】2022-12-1

緣由multisim汽車尾燈設計-學習和成長-CSDN問答 為什么模仿別人做的運行沒啥效果,啥也看不明白,數字電子技術要做的任務。

Langchain在調用 LLM 時統計 Token 消耗

關鍵點解析使用上下文管理器with get_openai_callback() as cb:這一行是核心。cb 會自動收集本次調用的 prompt tokens、completion tokens 以及 total tokens。自動統計在上下文退出時,cb 中已經包含了這次調用的消耗情況,無需額外手動計算。累加到全局…

漫談《數字圖像處理》之實時美顏技術

隨著移動拍攝、直播、短視頻等場景的普及,用戶對 “自然、流暢、可控” 的美顏效果需求日益提升 —— 既要消除皮膚瑕疵、優化面部形態,又需避免 “過度磨皮顯假”“變形失真”“實時卡頓” 等問題。實時美顏技術的核心并非單一算法的堆砌,而…

MATLAB基于PSO(粒子群算法)優化BP神經網絡和NSGA-II(非支配排序遺傳算法)多目標優化

代碼實現了一個智能算法優化BP神經網絡并進行多目標優化的完整流程,結合了PSO(粒子群算法)優化BP神經網絡和NSGA-II(非支配排序遺傳算法)多目標優化,用于多輸入多輸出的回歸預測問題。 ? 一、主要功能 數…

白平衡分塊統計數據為什么需要向下采樣?

在白平衡處理中,分塊統計數據時引入**向下采樣(Downsampling)**,核心目標是在保證統計有效性的前提下,解決“計算效率”與“統計魯棒性”的矛盾,同時避免局部噪聲對白平衡判斷的干擾。要理解這一設計的必要…

Deathnote: 1靶場滲透

Deathnote: 1 來自 <Deathnote: 1 ~ VulnHub> 1&#xff0c;將兩臺虛擬機網絡連接都改為NAT模式 2&#xff0c;攻擊機上做namp局域網掃描發現靶機 nmap -sn 192.168.23.0/24 那么攻擊機IP為192.168.23.128&#xff0c;靶場IP192.168.23.129 3&#xff0c;對靶機進行端口…

windows系統服務器測試部署springboot+vue+mysql項目

1. 后端Java應用啟動 直接使用命令行啟動&#xff08;推薦用于測試&#xff09;&#xff1a; cd C:\Users\Administrator\Desktop\toolset\backed java -jar -Dspring.profiles.activeprod -Dserver.port8083 admin.jar2. 前端靜態文件服務 由于你已經有了dist目錄&#xff0c;…

Java 與 Docker 的最佳實踐

在云原生時代&#xff0c;Docker 已成為應用交付和運行的事實標準。Java 作為企業級開發的主力語言&#xff0c;也需要與容器技術深度結合。然而&#xff0c;Java 程序天然有 JVM 內存管理、啟動速度、鏡像體積 等特點&#xff0c;如果不做優化&#xff0c;可能導致性能下降甚至…

大數據工程師認證推薦項目:基于Spark+Django的學生創業分析可視化系統技術價值解析

&#x1f496;&#x1f496;作者&#xff1a;計算機編程小央姐 &#x1f499;&#x1f499;個人簡介&#xff1a;曾長期從事計算機專業培訓教學&#xff0c;本人也熱愛上課教學&#xff0c;語言擅長Java、微信小程序、Python、Golang、安卓Android等&#xff0c;開發項目包括大…