知識庫 / Spring / Spring MVC RSS 訂閱

Spring MVC 中的 HandlerInterceptor 與 Filters 比較

Spring MVC
HongKong
4
12:31 PM · Dec 06 ,2025

1. 概述

本文將比較 Java Servlet 中的 Filter 與 Spring MVC 中的 HandlerInterceptor,並探討在何種情況下使用其中一種可能優於另一種。

2. 過濾器

過濾器是Web服務器的一部分,而不是Spring框架的一部分。對於傳入的請求,我們可以使用過濾器來操縱甚至阻止請求到達任何Servlet。反之,我們也可以阻止響應到達客户端。

Spring Security 是使用過濾器進行身份驗證和授權的絕佳例子。要配置 Spring Security,我們只需要添加一個過濾器,即 DelegatingFilterProxy。Spring Security 就可以攔截所有傳入和傳出的流量。 這也是為什麼 Spring Security 可以用於 Spring MVC 之外的原因。

2.1. 創建過濾器

為了創建過濾器,首先創建一個實現 javax.servlet.Filter 接口的類:

@Component
public class LogFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {
        logger.info("Hello from: " + request.getLocalAddr());
        chain.doFilter(request, response);
    }

}

接下來,我們覆蓋(override)doFilter 方法,在這個方法中,我們可以訪問或操作 ServletRequestServletResponseFilterChain 對象。我們可以使用 FilterChain 對象允許或阻止請求。

最後,我們通過在組件上添加 @Component 註解,將 Filter 添加到 Spring 上下文中。Spring 會完成剩餘的工作。

3. HandlerInterceptor 攔截器

HandlerInterceptors (攔截器) 是 Spring MVC 框架的一部分,位於 DispatcherServlet(分發器)和我們的 Controller(控制器)之間。 我們可以在請求到達控制器之前攔截請求,以及在視圖渲染之前和之後攔截請求。

3.1. 創建 HandlerInterceptor

要創建一個 HandlerInterceptor,我們需要創建一個實現 org.springframework.web.servlet.HandlerInterceptor 接口的類。這使我們能夠覆蓋三個方法:

  • preHandle() – 在調用目標處理程序之前執行
  • postHandle() – 在調用目標處理程序之後,但在 DispatcherServlet 渲染視圖之前執行
  • afterCompletion() – 在請求處理和視圖渲染完成後執行的回調

讓我們為三個方法在我們的測試攔截器中添加日誌記錄:

public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
      throws Exception {
        logger.info("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 
      throws Exception {
        logger.info("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
      throws Exception {
        logger.info("afterCompletion");
    }

}

4. 關鍵差異與使用場景

下面是一個圖表,展示了 FilterHandlerInterceptor 在請求/響應流程中的位置:

Filter 攔截請求在到達 DispatcherServlet 之前,使其成為執行粗粒度任務的理想選擇,例如:

  • 身份驗證
  • 日誌記錄和審計
  • 圖像和數據壓縮
  • 任何我們希望與 Spring MVC 解耦的功能

HandlerInterceptor,另一方面,在 DispatcherServlet 和我們的 Controller 之間攔截請求。 這在 Spring MVC 框架中完成,提供對 HandlerModelAndView 對象的訪問。 這減少了重複,並允許進行更精細的功能,例如:

  • 處理橫切關注點,例如應用程序日誌記錄
  • 詳細的授權檢查
  • 操作 Spring 應用程序上下文或模型

5. 結論

在本文中,我們探討了 FilterHandlerInterceptor 之間的差異。

關鍵要點是,使用 Filter 時,我們可以在請求到達控制器和 Spring MVC 之外之前對其進行操作。 否則,HandlerInterceptor 是處理應用程序特定橫向關注點的理想選擇。 通過提供對目標 HandlerModelAndView 對象的訪問權限,我們能夠獲得更精細的控制。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.