Servlet 2.3 引入 Filter,提供標準化的請求/回應攔截機制,取代早期專屬的「Servlet 鏈」。Filter 可:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
需求:`/resource/` 目錄下靜態檔案 (圖片、PDF、JS) 僅限登入用戶存取。
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() {}
}
<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 監控 |