Spring Boot攔截器Interceptor與過濾器Filter詳細(xì)教程(示例詳解)
Spring Boot攔截器(Interceptor)與過濾器(Filter)詳細(xì)教程
1. 概述
1.1 什么是攔截器(Interceptor)?
攔截器是 Spring MVC 框架的組件,基于 AOP(面向切面編程) 實現(xiàn)。它允許在請求處理的不同階段(如Controller方法執(zhí)行前后)插入自定義邏輯。
1.2 什么是過濾器(Filter)?
過濾器是 Java Servlet規(guī)范 定義的組件,作用于所有進(jìn)入容器的請求(如Tomcat)。它可以在請求到達(dá)Servlet前或響應(yīng)返回客戶端前進(jìn)行預(yù)處理和后處理。
1.3 核心區(qū)別
| 特性 | 攔截器(Interceptor) | 過濾器(Filter) |
|---|---|---|
| 所屬框架 | Spring MVC | Servlet API |
| 作用范圍 | 僅Spring MVC管理的請求 | 所有請求(包括靜態(tài)資源) |
| 依賴 | 依賴Spring容器 | 依賴Servlet容器(如Tomcat) |
| 執(zhí)行時機(jī) | Controller方法前后 | Servlet處理前后 |
| 獲取Bean | 支持(通過Spring上下文) | 不支持(需通過其他方式注入) |
2. 使用場景
2.1 攔截器的典型應(yīng)用
- 日志記錄:記錄請求參數(shù)、響應(yīng)時間。
- 權(quán)限驗證:檢查用戶是否登錄或擁有權(quán)限。
- 事務(wù)管理:在Controller方法前后開啟/提交事務(wù)。
- 性能監(jiān)控:統(tǒng)計接口耗時。
2.2 過濾器的典型應(yīng)用
- 全局字符編碼:統(tǒng)一設(shè)置請求/響應(yīng)的編碼(如UTF-8)。
- 跨域處理:添加CORS響應(yīng)頭。
- XSS防御:過濾請求參數(shù)中的惡意腳本。
- 請求壓縮:對響應(yīng)內(nèi)容進(jìn)行GZIP壓縮。
3. 實現(xiàn)步驟
3.1 創(chuàng)建攔截器
步驟:
實現(xiàn) HandlerInterceptor 接口,重寫以下方法:
preHandle():在Controller方法執(zhí)行前調(diào)用。postHandle():在Controller方法執(zhí)行后、視圖渲染前調(diào)用。afterCompletion():在請求完成后調(diào)用(視圖渲染后)。
注冊攔截器到Spring MVC配置。
代碼示例:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public 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 {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/static/**");
}
}注冊多個攔截器:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 第一個攔截器:日志(優(yōu)先級高)
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**") // 攔截所有路徑
.excludePathPatterns("/static/**"); // 排除靜態(tài)資源
// 第二個攔截器:權(quán)限(優(yōu)先級低)
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**"); // 僅攔截/api路徑
}
}關(guān)鍵配置選項
| 配置方法 | 說明 |
|---|---|
addPathPatterns("/api") | 指定攔截的路徑(支持Ant風(fēng)格) |
excludePathPatterns("/login") | 排除特定路徑 |
order(1) | 顯式設(shè)置順序(默認(rèn)按注冊順序) |
若要手動指定順序,可添加:
registry.addInterceptor(new LogInterceptor()).order(1); registry.addInterceptor(new AuthInterceptor()).order(2);
3.2 創(chuàng)建過濾器
步驟:
- 實現(xiàn)
javax.servlet.Filter接口,重寫doFilter方法。 - 注冊過濾器到Servlet容器(通過注解或配置類)。
代碼示例:
@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("請求開始: " + ((HttpServletRequest) request).getRequestURI());
chain.doFilter(request, response); // 繼續(xù)執(zhí)行后續(xù)過濾器或Servlet
System.out.println("請求結(jié)束");
}
}注冊過濾器(若未使用@WebFilter):
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LoggingFilter> loggingFilter() {
FilterRegistrationBean<LoggingFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new LoggingFilter());
bean.addUrlPatterns("/*");
bean.setOrder(1); // 設(shè)置執(zhí)行順序
return bean;
}
}注意: 確保主類添加 @ServletComponentScan 以啟用 @WebFilter 注解。
4. 執(zhí)行順序與流程
4.1 執(zhí)行順序
- 過濾器(FilterChain) → 2. 攔截器(preHandle) → 3. Controller方法 → 4. 攔截器(postHandle) → 5. 視圖渲染 → 6. 攔截器(afterCompletion) → 7. 過濾器后續(xù)處理
4.2 流程圖
客戶端 → Filter.doFilter() → Interceptor.preHandle()
→ Controller → Interceptor.postHandle()
→ 視圖渲染 → Interceptor.afterCompletion()
→ Filter.doFilter()后續(xù)處理 → 客戶端5. 常見問題與解決方案
Q1:如何控制多個攔截器/過濾器的執(zhí)行順序?
- 攔截器:通過
registry.addInterceptor()的順序決定。 - 過濾器:通過
FilterRegistrationBean.setOrder()設(shè)置優(yōu)先級(值越小越先執(zhí)行)。
Q2:攔截器中如何獲取Spring管理的Bean?
直接從Spring容器注入:
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService; // 直接注入
}Q3:過濾器中如何修改請求參數(shù)?
通過自定義 HttpServletRequestWrapper:
public class ModifyRequestWrapper extends HttpServletRequestWrapper {
// 重寫getParameter等方法以修改參數(shù)
}
// 在Filter中替換Request對象
chain.doFilter(new ModifyRequestWrapper(request), response);Q4:攔截器和過濾器執(zhí)行時出現(xiàn)異常如何處理?
- 攔截器:在
afterCompletion中處理異常。 - 過濾器:使用
try-catch包裹chain.doFilter()。
Q5:如何讓某個攔截器全局生效?
使用 addPathPatterns("/**"):
registry.addInterceptor(new LogInterceptor())
.addPathPatterns("/**");Q6:如何跳過特定攔截器的執(zhí)行?
在 preHandle 中返回 false:
@Override
public boolean preHandle(...) {
if (跳過條件) {
return false; // 后續(xù)攔截器和Controller不會執(zhí)行
}
return true;
}Q7:攔截器之間如何共享數(shù)據(jù)?
通過 request.setAttribute 傳遞:
// 在第一個攔截器中存儲數(shù)據(jù)
request.setAttribute("key", "value");
// 在后續(xù)攔截器中獲取
String value = (String) request.getAttribute("key");6. 總結(jié)
選擇攔截器還是過濾器?
- 需要訪問Spring上下文或Controller信息 → 攔截器。
- 需處理所有請求(包括靜態(tài)資源) → 過濾器。
最佳實踐:
- 優(yōu)先使用攔截器處理業(yè)務(wù)相關(guān)邏輯。
- 使用過濾器處理底層Servlet容器的任務(wù)(如編碼、壓縮)。
到此這篇關(guān)于Spring Boot攔截器(Interceptor)與過濾器(Filter)詳細(xì)教程的文章就介紹到這了,更多相關(guān)Spring Boot攔截器與過濾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入解析Spring MVC中攔截器Interceptor的實現(xiàn)原理和應(yīng)用場景
- Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對比分析
- SpringBoot使用Mybatis-Plus中分頁插件PaginationInterceptor詳解
- Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實現(xiàn)與實戰(zhàn)指南)
- Spring Mvc中攔截器Interceptor用法解讀
- Spring攔截器之HandlerInterceptor使用方式
- Spring的攔截器HandlerInterceptor詳解
- SpringMVC的處理器攔截器HandlerInterceptor詳解
- spring中Interceptor的使用小結(jié)
相關(guān)文章
java操作json對象出現(xiàn)StackOverflow錯誤的問題及解決
這篇文章主要介紹了java操作json對象出現(xiàn)StackOverflow錯誤的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
springboot集成swagger3與knife4j的詳細(xì)代碼
這篇文章主要介紹了springboot集成swagger3與knife4j,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08
springmvc fastjson 反序列化時間格式化方法(推薦)
下面小編就為大家?guī)硪黄猻pringmvc fastjson 反序列化時間格式化方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
Java 8 Stream 的終極技巧——Collectors 功能與操作方法詳解
這篇文章主要介紹了Java 8 Stream Collectors 功能與操作方法,結(jié)合實例形式詳細(xì)分析了Java 8 Stream Collectors 功能、操作方法及相關(guān)注意事項,需要的朋友可以參考下2020-05-05
解析和解決org.springframework.beans.factory.NoSuchBeanDefinitionE
這篇文章主要介紹了解析和解決org.springframework.beans.factory.NoSuchBeanDefinitionException異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
Springboot使用Selenium+ChormeDriver在服務(wù)器端將網(wǎng)頁保存為圖片或PDF
這篇文章主要為大家詳細(xì)介紹了Springboot使用Selenium+ChormeDriver在服務(wù)器端將網(wǎng)頁保存為圖片或PDF的相關(guān)方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-10-10
SpringBoot結(jié)合JSR303對前端數(shù)據(jù)進(jìn)行校驗的示例代碼
這篇文章主要介紹了SpringBoot結(jié)合JSR303對前端數(shù)據(jù)進(jìn)行校驗的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09

