SpringMvc(Interceptor,Filter)實現(xiàn)方案
在 Java Web 開發(fā)中,過濾器 (Filter) 和 攔截器 (Interceptor) 都是常用的 AOP(面向切面編程)實現(xiàn)方式,但它們所屬的框架層級和執(zhí)行時機有很大不同。
我們可以把它們想象成進入大樓的保安(過濾器)和進入辦公室前的秘書(攔截器)。
1. 過濾器 (Filter)
過濾器屬于 Servlet 規(guī)范,它位于所有 Servlet 之前。它可以對幾乎所有的請求(HTML、圖片、JS、路徑等)進行預處理。
實現(xiàn)方案一:通過@WebFilter注解(Servlet 原生)
這是最簡單、最直接的方式,不需要額外的配置類。
- 實現(xiàn)步驟:
- 實現(xiàn)
jakarta.servlet.Filter接口。 - 重寫
doFilter方法。 - 在類上標注
@WebFilter(urlPatterns = "/*")。 - 在啟動類上加
@ServletComponentScan。
- 實現(xiàn)
實現(xiàn)方案二:通過FilterRegistrationBean(Spring Boot統(tǒng)一管理生命周期 推薦)
如果你需要更精細地控制過濾器的執(zhí)行順序(Order),或者你的過濾器是第三方庫提供的,這種方案最合適。
- 實現(xiàn)步驟:
- 編寫一個普通的類實現(xiàn)
Filter接口。 - 創(chuàng)建一個配置類(標注
@Configuration)。 - 定義一個
Bean返回FilterRegistrationBean實例。
- 編寫一個普通的類實現(xiàn)
@Bean
public FilterRegistrationBean<MyFilter> registrationBean() {
FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new MyFilter()); // 設置過濾器
bean.addUrlPatterns("/api/*"); // 設置攔截路徑
bean.setOrder(1); // 設置優(yōu)先級,數(shù)字越小越靠前
return bean;
}2. 攔截器 (Interceptor)
攔截器屬于 Spring MVC 框架。它只能攔截發(fā)送到 Controller 的請求。因為它在 Spring 容器中,所以它可以直接使用 Spring 注入的對象(比如 Service)。
需要繼承/實現(xiàn)的類
- 實現(xiàn)接口:
org.springframework.web.servlet.HandlerInterceptor。 - 主要方法:
preHandle:在 Controller 執(zhí)行前調用(常用作權限校驗)。postHandle:Controller 執(zhí)行后,視圖渲染前調用。afterCompletion:整個請求結束(視圖渲染后)調用,常用于清理資源。
注冊攔截器
實現(xiàn)攔截器后,必須將其注冊到 Spring MVC 的配置中:
- 繼承
WebMvcConfigurer接口。 - 重寫
addInterceptors方法。
3. 核心區(qū)別對比表
| 特性 | 過濾器 (Filter) | 攔截器 (Interceptor) |
| 所屬框架 | Servlet 容器 (如 Tomcat) | Spring MVC 框架 |
| 實現(xiàn)接口 | jakarta.servlet.Filter | HandlerInterceptor |
| 攔截范圍 | 幾乎所有請求 (URL 匹配即可) | 僅針對 Controller 的請求 |
| 注入能力 | 較難直接注入 Spring Bean | 完美支持注入 Bean |
| 執(zhí)行時機 | 在 Servlet 之前執(zhí)行 | 在 Servlet 之后,Controller 之前執(zhí)行 |
| 主要用途 | 編碼設置、敏感詞過濾、全局壓縮 | 權限檢查、日志記錄、參數(shù)預處理 |
簡單總結:
- 過濾器:適合做底層的、通用的操作(如:字符編碼、請求跨域、全局加密)。
- 攔截器:適合做業(yè)務相關的操作(如:檢查是否登錄、接口權限控制、記錄操作日志)。
為什么跨域請求要通過過濾器實現(xiàn)?
其實跨域(CORS)既可以通過**過濾器(Filter)實現(xiàn),也可以通過攔截器(Interceptor)**或者 Spring 提供的 @CrossOrigin 注解實現(xiàn)。
但在實際生產(chǎn)中,絕大多數(shù)架構師會首選過濾器。這主要源于跨域請求的一個特殊機制:預檢請求(Preflight Request)。
1. 預檢請求(OPTIONS)的攔路虎
當瀏覽器發(fā)現(xiàn)你在發(fā)起一個“復雜請求”(比如帶了自定義 Header 或 Content-Type 為 application/json)時,它會先自動發(fā)送一個 OPTIONS 方法的探測請求。
- 過濾器的優(yōu)勢:由于過濾器在 Servlet 容器的最外層,它能在請求到達 Spring MVC 的
DispatcherServlet之前,就識別出這是一個 OPTIONS 請求,并直接返回允許跨域的響應頭(200 OK)。 - 攔截器的劣勢:攔截器工作在 Spring MVC 內部。如果你的 OPTIONS 請求因為某些安全配置或權限校驗沒能通過
DispatcherServlet的映射,攔截器可能根本不會執(zhí)行。這會導致預檢請求失敗,瀏覽器直接攔截掉后續(xù)的正式請求。
2. 為什么選擇過濾器的三大理由
① 執(zhí)行時機最早(最核心原因)
跨域配置本質上是給 HTTP 響應頭加上 Access-Control-Allow-Origin 等字段。
- 過濾器在整個過濾鏈的最前端。如果請求跨域失敗,直接在過濾器層級就“擋回去”或“處理掉”了,不會浪費后續(xù)的業(yè)務邏輯資源(如數(shù)據(jù)庫連接、權限檢查)。
② 解決權限框架(Security/Shiro)的沖突
如果你的項目中使用了 Spring Security,它本身就是通過一系列過濾器實現(xiàn)的。
- 如果你把跨域放在攔截器里,由于攔截器的執(zhí)行晚于 Spring Security 的過濾器,Spring Security 會在攔截器生效前發(fā)現(xiàn)請求沒帶 Token 或不符合安全規(guī)則,直接返回 403。
- 此時瀏覽器因為沒收到跨域響應頭,會報一個“CORS error”,而隱藏了真正的“403 Forbidden”錯誤,導致前端無法準確定位問題。
③ 覆蓋范圍廣
過濾器是針對 URL 模式攔截的。如果你的項目里既有 Spring MVC 的 Controller,又有一些原生的 Servlet,或者靜態(tài)資源,過濾器可以一把抓,統(tǒng)一處理所有資源的跨域問題。
3. 實現(xiàn)代碼對比
過濾器方案(推薦)
這種方式利用 Spring 提供的 CorsFilter,通常配合 FilterRegistrationBean 使用,優(yōu)先級設為最高。
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*"); // 允許所有來源
config.addAllowedHeader("*"); // 允許所有Header
config.addAllowedMethod("*"); // 允許所有方法
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE); // 確保在最前端執(zhí)行
return bean;
}總結
跨域選擇過濾器,是因為它能在業(yè)務邏輯和安全框架之前處理 OPTIONS 請求。就像在大樓的**正門口(過濾器)貼上“歡迎光臨”的告示,比等客人進了辦公室(攔截器)**才說歡迎要高效且穩(wěn)妥得多。
到此這篇關于SpringMvc(Interceptor,Filter)實現(xiàn)方案的文章就介紹到這了,更多相關SpringMvc Interceptor,Filter內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 淺談SpringMVC的攔截器(Interceptor)和Servlet 的過濾器(Filter)的區(qū)別與聯(lián)系 及SpringMVC 的配置文件
- 淺談SpringMVC中Interceptor和Filter區(qū)別
- SpringMVC的處理器攔截器HandlerInterceptor詳解
- SpringMVC中的ConversionServiceExposingInterceptor工具類解析
- SpringMVC中的ResourceUrlProviderExposingInterceptor詳解
- SpringMVC Interceptor攔截器使用教程
- springMVC攔截器HandlerInterceptor用法代碼示例
- 詳解SpringMVC中使用Interceptor攔截器
相關文章
Java HashMap源碼及并發(fā)環(huán)境常見問題解決
這篇文章主要介紹了Java HashMap源碼及并發(fā)環(huán)境常見問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09
SpringBoot頂層接口實現(xiàn)類注入項目的方法示例
本文主要介紹了SpringBoot頂層接口實現(xiàn)類注入項目的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-06-06
WebUploader客戶端批量上傳圖片 后臺使用springMVC
這篇文章主要為大家詳細介紹了WebUploader客戶端批量上傳圖片,后臺使用springMVC接收實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09
SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析(最新推薦)
Spring?Boot?對于?Spring?Security?提供了自動化配置方案,可以使用更少的配置來使用?Spring?Security,這篇文章主要介紹了SpringBoot整合Spring?Security過濾器鏈加載執(zhí)行流程源碼分析,需要的朋友可以參考下2023-02-02
Java之SpringCloudAlibaba Sentinel組件案例講解
這篇文章主要介紹了Java之SpringCloudAlibaba Sentinel組件案例講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-07-07

