首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Servlet Filter 實戰:從核心 API 到登入攔截完整範例

     編輯:Java 相關知識

Filter 核心價值

Servlet 2.3 引入 Filter,提供標準化的請求/回應攔截機制,取代早期專屬的「Servlet 鏈」。Filter 可:

  • 檢查/修改請求 (`ServletRequest`)
  • 決定是否放行 (`chain.doFilter()`)
  • 修改回應 (`ServletResponse` 包裝)
  • 完全阻擋並自行產生回應

Filter 開發五步驟

  1. 實作 `javax.servlet.Filter` 介面 (`doFilter`, `init`, `destroy`)
  2. 在 `doFilter` 撰寫攔截邏輯
  3. 呼叫 `chain.doFilter(req, res)` 放行或自行處理
  4. 在 `web.xml` 註冊 `` + ``
  5. 禁用預設 Servlet 映射防止繞過 (如 `/resource/*` 靜態資源)

核心 API 深度解析

1. doFilter 三參數

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException
  • `request`:常轉型 `HttpServletRequest` 取 Header、Parameter、Session、Cookie
  • `response`:通常忽略,除非阻擋請求自行輸出 或 包裝回應修改輸出
  • `chain`:呼叫 `chain.doFilter()` 激活下一個 Filter 或目標 Servlet/JSP

2. init(FilterConfig config)

  • 僅初始化執行一次,可取得 ``、ServletContext、Filter 名稱
  • 常見模式:將 `FilterConfig` 存為實例變數供 `doFilter` 使用

3. destroy()

  • 容器卸載 Filter 時呼叫,釋放資料庫連線池、檔案控制代等資源

實戰案例:靜態資源登入保護

需求:`/resource/` 目錄下靜態檔案 (圖片、PDF、JS) 僅限登入用戶存取。

Filter 實作

public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false); // 不自動建立
        
        // 檢查登入標記
        if (session == null || session.getAttribute("userSession") == null) {
            // 未登入 → 重導錯誤頁 (需排除錯誤頁本身避免迴圈)
            String loginUrl = request.getContextPath() + "/error/priv_error.jsp";
            if (!request.getRequestURI().equals(loginUrl)) {
                response.sendRedirect(loginUrl);
            }
            return; // 關鍵:不呼叫 chain.doFilter(),攔截結束
        }
        
        // 已登入 → 放行
        chain.doFilter(request, response);
    }
    
    @Override public void init(FilterConfig config) {}
    @Override public void destroy() {}
}

web.xml 註冊

<filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>com.myapp.filter.AuthFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/resource/*</url-pattern>
</filter-mapping>

進階應用模式

模式關鍵技術應用場景
請求包裝`HttpServletRequestWrapper` 重寫 `getParameter()`XSS 過濾、參數解密、統一編碼設定
回應包裝`HttpServletResponseWrapper` + `ByteArrayOutputStream`頁面壓縮 (GZIP)、敏感詞過濾、全站頁尾注入
跨域處理 (CORS)在 `doFilter` 設定 `Access-Control-Allow-*` Header前後端分離 API 跨域
效能監控`System.nanoTime()` 計算耗時,記錄慢查詢APM 埋點、SLA 監控

Filter 鏈順序與最佳實踐

  1. 順序由 `` 宣告順序決定,編碼 Filter 應最先執行
  2. Spring `DelegatingFilterProxy` 整合 Spring Bean Filter,支援依賴注入
  3. Spring Boot 使用 `FilterRegistrationBean` 程式化註冊,可設定 `Order`
  4. 靜態資源保護:Nginx 層面 `auth_request` 模組分流,減輕 Java 應用壓力
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved