溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

過濾器Filter和攔截器HandlerIntercepter的區別及用法

發布時間:2021-06-23 09:30:06 來源:億速云 閱讀:659 作者:chen 欄目:大數據
# 過濾器Filter和攔截器HandlerIntercepter的區別及用法

## 目錄
1. [概述](#概述)
2. [核心概念解析](#核心概念解析)
   - [2.1 過濾器(Filter)](#21-過濾器filter)
   - [2.2 攔截器(HandlerInterceptor)](#22-攔截器handlerinterceptor)
3. [工作原理對比](#工作原理對比)
   - [3.1 執行時機](#31-執行時機)
   - [3.2 作用范圍](#32-作用范圍)
   - [3.3 實現機制](#33-實現機制)
4. [代碼實現詳解](#代碼實現詳解)
   - [4.1 Filter實現示例](#41-filter實現示例)
   - [4.2 Interceptor實現示例](#42-interceptor實現示例)
5. [應用場景分析](#應用場景分析)
   - [5.1 Filter適用場景](#51-filter適用場景)
   - [5.2 Interceptor適用場景](#52-interceptor適用場景)
6. [Spring中的整合使用](#spring中的整合使用)
7. [性能對比與注意事項](#性能對比與注意事項)
8. [常見問題解答](#常見問題解答)
9. [總結](#總結)

## 概述

在Java Web開發中,過濾器和攔截器是兩種重要的請求處理機制,它們都能對HTTP請求進行預處理和后處理,但在實現原理和應用場景上存在本質區別。本文將深入分析兩者的技術差異,并通過實際代碼示例展示它們的典型用法。

## 核心概念解析

### 2.1 過濾器(Filter)

**定義**:Filter是Servlet規范定義的組件,基于函數回調實現,作用于Web容器層面。

**核心特性**:
- 屬于J2EE標準組件
- 在請求進入Servlet容器后、到達Servlet之前執行
- 可以修改請求/響應對象(裝飾器模式)
- 配置在web.xml或通過@WebFilter注解

**生命周期**:
```java
init(FilterConfig) → doFilter(ServletRequest, ServletResponse, FilterChain) → destroy()

2.2 攔截器(HandlerInterceptor)

定義:Interceptor是Spring MVC框架提供的機制,基于AOP思想實現,作用于DispatcherServlet之后。

核心特性: - Spring框架特有組件 - 可以訪問HandlerMethod上下文 - 支持更精細的攔截控制(如基于路徑模式) - 通過實現接口并注冊到InterceptorRegistry

方法組成

preHandle() → postHandle() → afterCompletion()

工作原理對比

3.1 執行時機

階段 Filter Interceptor
容器初始化 ? ×
進入DispatcherServlet前 ? ×
Controller方法調用前 × ?
視圖渲染前 × ?
請求完成時 ? ?

典型調用鏈:

HTTP請求 → 容器 → FilterChain → DispatcherServlet → Interceptor → Controller

3.2 作用范圍

Filter: - 對所有請求生效(包括靜態資源) - 可以修改請求/響應內容 - 無法獲取Spring上下文信息

Interceptor: - 僅對Controller請求生效 - 可以訪問HandlerMethod參數 - 能與Spring其他組件(如Service)交互

3.3 實現機制

Filter 采用責任鏈模式:

public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) {
    // 前置處理
    chain.doFilter(wrappedRequest, wrappedResponse); 
    // 后置處理
}

Interceptor 基于攔截器棧:

boolean preHandle(...) {
    // 返回true繼續執行后續攔截器
}
void postHandle(...) {
    // 視圖渲染前處理
}

代碼實現詳解

4.1 Filter實現示例

日志過濾器

@WebFilter("/*")
public class LogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, 
            FilterChain chain) throws IOException, ServletException {
        
        long start = System.currentTimeMillis();
        HttpServletRequest request = (HttpServletRequest) req;
        
        // 記錄請求信息
        System.out.printf("Request URI: %s%n", request.getRequestURI());
        
        chain.doFilter(req, res);  // 關鍵調用
        
        // 記錄響應時間
        System.out.printf("Request %s completed in %dms%n", 
            request.getRequestURI(),
            System.currentTimeMillis() - start);
    }
}

注冊方式: 1. 注解方式:@WebFilter(urlPatterns = "/*") 2. XML配置:

<filter>
    <filter-name>logFilter</filter-name>
    <filter-class>com.example.LogFilter</filter-class>
</filter>

4.2 Interceptor實現示例

權限攔截器

public class AuthInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler) throws Exception {
        
        if (!checkAuth(request)) {
            response.sendError(403, "Forbidden");
            return false;  // 中斷請求
        }
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler, 
            ModelAndView modelAndView) {
        // 可添加全局模型數據
        modelAndView.addObject("version", "1.0.0");
    }
}

注冊配置

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/public/**");
    }
}

應用場景分析

5.1 Filter適用場景

  1. 跨域處理
response.setHeader("Access-Control-Allow-Origin", "*");
  1. 請求/響應包裝
chain.doFilter(new XSSRequestWrapper(request), response);
  1. 全局編碼設置
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
  1. 敏感詞過濾
String content = request.getParameter("content");
content = SensitiveWordFilter.replace(content);

5.2 Interceptor適用場景

  1. 權限驗證
if (request.getSession().getAttribute("user") == null) {
    response.sendRedirect("/login");
    return false;
}
  1. 接口耗時統計
long start = System.currentTimeMillis();
request.setAttribute("startTime", start);
  1. 參數預處理
String token = request.getHeader("X-Token");
TokenUtils.verify(token);
  1. 日志記錄
log.info("{} {} from {}", 
    request.getMethod(), 
    request.getRequestURI(),
    request.getRemoteAddr());

Spring中的整合使用

組合應用示例

請求 → EncodingFilter → SecurityFilter → DispatcherServlet → 
      LogInterceptor → AuthInterceptor → Controller

執行順序控制: 1. Filter順序:通過@Order注解或web.xml中<filter-mapping>順序 2. Interceptor順序:注冊時的添加順序

注意事項: - 避免在Filter和Interceptor中重復處理相同邏輯 - Filter中拋出的異常不會被@ControllerAdvice捕獲 - Interceptor的postHandle在@ResponseBody方法中不會執行

性能對比與注意事項

性能指標

維度 Filter Interceptor
執行效率 更高(容器級) 稍低(反射調用)
資源消耗 更低 更高
功能豐富度 基礎 強大

最佳實踐: 1. 優先使用Interceptor處理業務相關邏輯 2. 在需要修改請求/響應內容時使用Filter 3. 靜態資源處理應使用Filter 4. 避免在Filter中注入Spring Bean(需通過DelegatingFilterProxy)

常見陷阱

// Filter中錯誤示例
chain.doFilter(request, response);
response.getWriter().write("extra content"); // 可能被覆蓋

// Interceptor中錯誤示例
preHandle返回false時未處理響應

常見問題解答

Q1:如何選擇使用Filter還是Interceptor? A:考慮三個關鍵因素: 1. 是否需要修改請求/響應內容 → 選Filter 2. 是否需要訪問HandlerMethod信息 → 選Interceptor 3. 是否需要攔截靜態資源 → 選Filter

Q2:能否在Filter中注入Spring Bean? A:常規Filter不能直接注入,解決方案: 1. 使用DelegatingFilterProxy 2. 實現ApplicationContextAware接口 3. 通過@Autowired靜態成員(不推薦)

Q3:執行順序異常如何排查? A:檢查以下配置: 1. web.xml中filter-mapping順序 2. @WebFilter的order屬性 3. InterceptorRegistry的添加順序

總結

核心差異總結表

對比維度 Filter Interceptor
規范標準 Servlet規范 Spring框架
作用階段 Servlet前后 Handler執行前后
可訪問信息 原始Request/Response HandlerMethod上下文
配置方式 web.xml/@WebFilter JavaConfig/XML
異常處理 容器處理 Spring統一異常處理

技術選型建議: - 基礎架構層功能(編碼、安全等)→ Filter - 業務相關控制(權限、日志等)→ Interceptor - 復雜場景可組合使用,但需注意執行順序

未來發展趨勢: 1. 隨著Servlet異步IO的發展,Filter需要適配異步場景 2. Interceptor在Spring WebFlux中有相應替代方案 3. 注解驅動的攔截方式逐漸成為主流 “`

(注:實際文檔字數為約4500字,完整5450字版本需要擴展每個章節的示例分析和原理詳解部分)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女