Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)
Spring Boot攔截器(Interceptor)與過濾器(Filter)深度解析:區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南
一、核心概念對比
1. 本質(zhì)區(qū)別
| 維度 | 過濾器(Filter) | 攔截器(Interceptor) |
|---|---|---|
| 規(guī)范層級 | Servlet規(guī)范(J2EE標(biāo)準(zhǔn)) | Spring MVC框架機(jī)制 |
| 作用范圍 | 所有請求(包括靜態(tài)資源) | 只處理Controller請求 |
| 依賴關(guān)系 | 不依賴Spring容器 | 完全集成Spring IOC容器 |
| 執(zhí)行順序 | 最先執(zhí)行(在DispatcherServlet之前) | 在DispatcherServlet之后執(zhí)行 |
| 異常處理 | 無法直接使用Spring的異常處理機(jī)制 | 可以通過@ControllerAdvice統(tǒng)一處理 |
2. 執(zhí)行流程示意圖
HTTP Request ↓ Filter Chain(doFilter) ↓ DispatcherServlet ↓ Interceptor.preHandle ↓ Controller Method ↓ Interceptor.postHandle ↓ View Rendering(如有) ↓ Interceptor.afterCompletion ↓ Filter Chain(返回響應(yīng))
二、過濾器(Filter)開發(fā)指南
1. 基礎(chǔ)實(shí)現(xiàn)方式
@Component
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
long startTime = System.currentTimeMillis();
HttpServletRequest req = (HttpServletRequest) request;
// 前置處理
System.out.println("Request URI: " + req.getRequestURI());
chain.doFilter(request, response); // 放行請求
// 后置處理
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request completed in " + duration + "ms");
}
}2. 高級配置技巧
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LogFilter> loggingFilter() {
FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new LogFilter());
registration.addUrlPatterns("/api/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 設(shè)置優(yōu)先級
return registration;
}
}典型應(yīng)用場景:
- 請求日志記錄
- 全局字符編碼設(shè)置
- 跨域處理(CORS)
- XSS防御過濾
- 請求內(nèi)容壓縮/解壓
三、攔截器(Interceptor)開發(fā)指南
1. 標(biāo)準(zhǔn)實(shí)現(xiàn)模板
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (!validateToken(token)) {
response.sendError(401, "Invalid token");
return false; // 中斷請求
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// Controller方法執(zhí)行后,視圖渲染前
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 請求完全結(jié)束后(包括視圖渲染)
}
}2. 注冊攔截器配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login", "/public/**");
}
}典型應(yīng)用場景:
- 接口權(quán)限驗(yàn)證
- 請求參數(shù)預(yù)處理
- 接口耗時(shí)監(jiān)控
- 敏感操作日志
- 數(shù)據(jù)綁定前校驗(yàn)
四、核心差異深度解析
1. 執(zhí)行順序?qū)Ρ葘?shí)驗(yàn)
配置多個(gè)過濾器和攔截器時(shí)的執(zhí)行順序:
Filter1 → Filter2 → Interceptor.preHandle → Controller → Interceptor.postHandle → Interceptor.afterCompletion → Filter2 → Filter1
2. 異常處理差異
// 在過濾器中處理異常
public void doFilter(...) {
try {
chain.doFilter(request, response);
} catch (Exception e) {
response.sendError(500, "Server Error");
}
}
// 在攔截器中處理異常
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
return ResponseEntity.internalServerError().body("Error occurred");
}
}3. 異步請求處理
// 攔截器需實(shí)現(xiàn)AsyncHandlerInterceptor
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 異步請求的特殊處理
}五、最佳實(shí)踐與選型策略
1. 技術(shù)選型決策樹
是否需要處理靜態(tài)資源?
├─ 是 → 必須使用Filter
└─ 否 →
是否需要訪問Spring Bean?
├─ 是 → 選擇Interceptor
└─ 否 →
是否需要最早處理請求?
├─ 是 → 選擇Filter
└─ 否 → 根據(jù)業(yè)務(wù)復(fù)雜度選擇2. 性能優(yōu)化建議
- 過濾器:避免在過濾器中做復(fù)雜業(yè)務(wù)邏輯
- 攔截器:preHandle方法盡量輕量化
- 兩者都應(yīng)避免:
- 同步阻塞操作
- 頻繁的IO操作
- 大對象的內(nèi)存操作
3. 常見陷阱規(guī)避
- 過濾器:
- 忘記調(diào)用chain.doFilter()導(dǎo)致請求阻塞
- 修改請求參數(shù)未使用Wrapper類
- 攔截器:
- 在postHandle中修改ModelAndView導(dǎo)致NPE
- 異步請求中誤用afterCompletion
六、實(shí)戰(zhàn)案例演示
案例1:接口耗時(shí)監(jiān)控系統(tǒng)
// 攔截器實(shí)現(xiàn)
public class MetricsInterceptor implements HandlerInterceptor {
private static final ThreadLocal<Long> startTime = new ThreadLocal<>();
@Override
public boolean preHandle(...) {
startTime.set(System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(...) {
long duration = System.currentTimeMillis() - startTime.get();
metricsService.recordRequestTime(request.getRequestURI(), duration);
startTime.remove();
}
}案例2:全局防重放攻擊過濾器
public class ReplayAttackFilter implements Filter {
private Cache<String, Boolean> requestCache =
Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
@Override
public void doFilter(...) {
String nonce = request.getHeader("X-Nonce");
if (requestCache.getIfPresent(nonce) != null) {
response.sendError(400, "Duplicate request");
return;
}
requestCache.put(nonce, true);
chain.doFilter(request, response);
}
}七、擴(kuò)展知識
1. 與AOP的區(qū)別
- AOP:
- 基于代理模式實(shí)現(xiàn)
- 可以精確控制到具體方法
- 更適合業(yè)務(wù)層面的切面處理
- 攔截器:
- 基于HandlerMapping實(shí)現(xiàn)
- 主要針對HTTP請求生命周期
- 更適合Web層通用處理
2. 高級應(yīng)用場景
- 過濾器鏈:實(shí)現(xiàn)責(zé)任鏈模式
- 攔截器棧:組合多個(gè)攔截邏輯
- 動(dòng)態(tài)啟用/禁用:結(jié)合配置中心實(shí)現(xiàn)
總結(jié)建議
- 優(yōu)先使用攔截器處理Web層通用邏輯
- 保留過濾器用于底層請求處理
- 復(fù)雜場景可以組合使用兩者
- 生產(chǎn)環(huán)境務(wù)必進(jìn)行性能壓測
通過合理運(yùn)用過濾器和攔截器,開發(fā)者可以構(gòu)建出高可維護(hù)性的Web應(yīng)用架構(gòu)。建議結(jié)合APM工具(如SkyWalking)監(jiān)控兩者的執(zhí)行效率,持續(xù)優(yōu)化系統(tǒng)性能。
到此這篇關(guān)于Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)的文章就介紹到這了,更多相關(guān)Spring Boot攔截器Interceptor與過濾器Filter區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入解析Spring MVC中攔截器Interceptor的實(shí)現(xiàn)原理和應(yīng)用場景
- Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對比分析
- SpringBoot使用Mybatis-Plus中分頁插件PaginationInterceptor詳解
- Spring Mvc中攔截器Interceptor用法解讀
- Spring Boot攔截器Interceptor與過濾器Filter詳細(xì)教程(示例詳解)
- Spring攔截器之HandlerInterceptor使用方式
- Spring的攔截器HandlerInterceptor詳解
- SpringMVC的處理器攔截器HandlerInterceptor詳解
- spring中Interceptor的使用小結(jié)
相關(guān)文章
?基于Java解決華為機(jī)試之字符串合并處理實(shí)操
這篇文章主要介紹了基于Java解決華為機(jī)試之字符串合并處理,文章以實(shí)操展開主題內(nèi)容,具有一的參考價(jià)值,需要的小伙伴可以參考一下,希望對工作中的你有所幫助2022-02-02
Javaweb mybatis接口開發(fā)實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Javaweb mybatis接口開發(fā)實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
springboot如何解決跨域后session獲取不到sessionId不一致
這篇文章主要介紹了springboot如何解決跨域后session獲取不到sessionId不一致問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
使用Backoff策略提高HttpClient連接管理的效率
這篇文章主要為大家介紹了Backoff策略提高HttpClient連接管理的效率使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
關(guān)于SpringBoot 打包成的可執(zhí)行jar不能被其他項(xiàng)目依賴的問題
這篇文章主要介紹了關(guān)于SpringBoot 打包成的可執(zhí)行jar不能被其他項(xiàng)目依賴的問題,本文給大家通過圖文實(shí)例相結(jié)合給大家分享解決方法,需要的朋友可以參考下2020-10-10
Springboot項(xiàng)目快速實(shí)現(xiàn)攔截器功能
上一篇文章介紹了Springboot項(xiàng)目如何快速實(shí)現(xiàn)過濾器功能,本篇文章接著來盤一盤攔截器,仔細(xì)研究后會發(fā)現(xiàn),其實(shí)攔截器和過濾器的功能非常類似,可以理解為面向切面編程的一種具體實(shí)現(xiàn)。感興趣的小伙伴可以參考閱讀2023-03-03

