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

Servlet Filter 實戰:基於 JBuilder 2005 實現登錄攔截與編碼統一處理

     編輯:Java 程式設計入門

Filter 核心價值:橫切關注點的集中管控

Servlet Filter(過濾器)能在請求到達 Servlet/JSP 前、響應返回客戶端前插入邏輯,完美解決多頁面共性需求:

  • 編碼統一:消除跨平台、跨容器的亂碼顧慮。
  • 頁面裝飾:統一注入頁首、頁尾、導航欄。
  • 安全攔截:會話驗證、權限校驗、未登錄重定向。
  • 日誌審計:請求參數、耗時、異常記錄。
  • 壓縮/緩存:GZIP 壓縮響應、靜態資源緩存頭設置。

實戰案例:登錄狀態攔截器

開發步驟(JBuilder 2005 向導)

  1. File → New → Web → Filter Servlet 啟動向導。
  2. 類名:LoginCheckFilter,包:bookstore.servlet。
  3. URL Pattern:/*(攔截所有請求),Filter Name:logincheckfilter。

核心代碼實現

package bookstore.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class LoginCheckFilter implements Filter {

    private FilterConfig filterConfig;

    @Override
    public void init(FilterConfig config) {
        this.filterConfig = config;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        String uri = req.getRequestURI().toUpperCase();
        boolean isLoginPage = uri.contains("LOGIN.JSP") || uri.contains("SWITCH.JSP");
        boolean isLoggedIn = req.getSession().getAttribute("ses_userBean") != null;

        // 登錄頁或已登錄 → 放行
        if (isLoginPage || isLoggedIn) {
            chain.doFilter(request, response);
        } else {
            // 未登錄 → 重定向至登錄頁
            resp.sendRedirect(req.getContextPath() + "/login.jsp");
        }
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }
}

關鍵點解析

  • 放行條件:白名單路徑(登錄頁、切換頁)+ 會話存在用戶對象。
  • 重定向用 sendRedirect:客戶端跳轉,地址欄變化,避免表單重複提交。
  • 獲取上下文路徑:req.getContextPath() 確保部署路徑變更不影響。
  • 異常處理:捕獲 ServletException/IOException 記錄日誌,不拋出避免中斷鏈路。

進階擴展:編碼過濾器

public class EncodingFilter implements Filter {
    private String encoding = "UTF-8";
    private boolean forceEncoding = true;

    @Override
    public void init(FilterConfig config) {
        String enc = config.getInitParameter("encoding");
        if (enc != null) encoding = enc;
        String force = config.getInitParameter("forceEncoding");
        if (force != null) forceEncoding = Boolean.parseBoolean(force);
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        if (forceEncoding || req.getCharacterEncoding() == null) {
            req.setCharacterEncoding(encoding);
        }
        if (forceEncoding || resp.getCharacterEncoding() == null) {
            resp.setCharacterEncoding(encoding);
        }
        chain.doFilter(req, resp);
    }
}

web.xml 配置:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>bookstore.servlet.EncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Filter 鏈順序與最佳實踐

  1. 編碼過濾器最先:確保後續 Filter 讀取參數時編碼正確。
  2. 安全過濾器次之:早攔截未授權請求,節省資源。
  3. 業務過濾器最後:日誌、壓縮等非核心邏輯。
  4. 避免在 Filter 中處理業務邏輯:職責單一,複雜業務交由 Controller/Service。
  5. 異常不吞噬:記錄後拋出或交由容器錯誤頁處理。

總結

Filter 是 Java Web 架構中實現 AOP 風格橫切關注點的輕量級利器。善用 Filter 可大幅減少重複代碼,提升系統安全性、可維護性與一致性。JBuilder 等 IDE 的向導能加速樣板代碼生成,但核心邏輯仍需開發者深入理解 Servlet API 與 HTTP 協議。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved