過濾器(Filter)
本文摘自servlet3.1規範
過濾器(Filter)是 Java 組件,允許運行過程中改變進入資源的請求和資源返回的響應中的有效負載和 header
信息。
本章描述了 Java Servlet v3.0 API 類和方法,它們提供了一種輕量級的框架用於過濾動態和靜態內容。還描
述了如何在 Web 應用配置 Filter,它們實現的約定和語義。
網上提供了 Servlet 過濾器的 API 文檔。過濾器的配置語法在第 14 章的“部署描述符”中的部署描述符模
式部分給出。當閱讀本章時,讀者應該是一這些資源作為參考。
什麽是過濾器?
過濾器是一種代碼重用的技術,它可以改變 HTTP 請求的內容,響應,及 header 信息。過濾器通常不產生
過濾器可以作用於動態或靜態內容。這章說的動態和靜態內容指的是 Web 資源。
供開發人員使用的過濾器功能有如下幾種類型:
■ 在執行請求之前訪問資源。
■ 在執行請求之前處理資源的請求。
■ 用請求對象的自定義版本包裝請求對請求的 header 和數據進行修改。
■ 用響應對象的自定義版本包裝響應對響應的 header 和數據進行修改。
■ 攔截資源調用之後的調用。
■ 作用在 Servlet,一組 Servlet,或靜態內容上的零個,一個或多個攔截器按指定的順序執行。
過濾器組件示例:
■ 驗證過濾器
■ 圖像轉換過濾器
■ 數據壓縮過濾器
■ 加密過濾器
■ 詞法(Tokenizing)過濾器
■ 觸發資源訪問事件過濾器
■ 轉換 XML 內容的 XSL/T 過濾器
■ MIME-類型鏈過濾器
■ 緩存過濾器
應用開發人員通過實現 javax.servlet.Filter 接口並提供一個公共的空參構造器來創建過濾器。該類及構建
Web 應用的靜態資源和 Servlet 打包在 Web 應用歸檔文件中。Filter 在部署描述符中通過<filter>元素聲明。
一個過濾器或一組過濾器可以通過在部署描述符中定義<filter-mapping>來為調用配置。可以使用 servlet 的
過濾器。
過濾器的生命周期?
在 Web 應用部署之後,在請求導致容器訪問 Web 資源之前,容器必須找到過濾器列表並按照如上所述的應
用到 Web 資源。容器必須確保它為過濾器列表中的每一個都實例化了一個適當類的過濾器,並調用其
init(FilterConfig config)方法。過濾器可能會拋出一個異常,以表明它不能正常運轉。如果異常的類型是
UnavailableException,容器可以檢查異常的 isPermanent 屬性並可以選擇稍候重試過濾器。
在部署描述符中聲明的每個<filter>在每個 JVM 的容器中僅實例化一個實例。容器提供了聲明在過濾器的部
署描述符的過濾器 config(譯者註:FilterConfig),對 Web 應用的 ServletContext 的引用,和一組初始化參
數。
當容器接收到傳入的請求時,它將獲取列表中的第一個過濾器並調用 doFilter 方法,傳入 ServletRequest 和
ServletResponse,和一個它將使用的 FilterChain 對象的引用。
過濾器的 doFilter 方法通常會被實現為如下或如下形式的子集:
1. 該方法檢查請求的頭。
2. 該方法可以用自定義的ServletRequest或HttpServletRequest實現包裝請求對象為了修改請求的頭或數據。
3. 該方法可以用自定義的ServletResponse 或 HttpServletResponse實現包裝傳入doFilter方法的響應對象用
於修改響應的頭或數據。
4. 該過濾器可以調用過濾器鏈中的下一個實體。下一個實體可能是另一個過濾器,或者如果當前調用的過
濾器是該過濾器鏈配置在部署描述符中的最後一個過濾器,下一個實體是目標 Web 資源。調用 FilterChain
對象的 doFilter 方法將影響下一個實體的調用,且傳入的它被調用時請求和響應,或傳入它可能已經創建
的包裝版本。
由容器提供的過濾器鏈的 doFilter 方法的實現,必須找出過濾器鏈中的下一個實體並調用它的 doFilter 方法,
傳入適當的請求和響應對象。另外,過濾器鏈可以通過不調用下一個實體來阻止請求,離開過濾器負責填
充響應對象。
service 方法必須和應用到 servlet 的所有過濾器運行在同一個線程中。
5. 過濾器鏈中的下一個過濾器調用之後,過濾器可能檢查響應的頭。
6. 另外,過濾器可能拋出一個異常以表示處理過程中出錯了。如果過濾器在 doFilter 處理過程中拋出
UnavailableException,容器必須停止處理剩下的過濾器鏈。 如果異常沒有標識為永久的,它或許選擇稍候
重試整個鏈。
7. 當鏈中的最後的過濾器被調用,下一個實體訪問的是鏈最後的目標 servlet 或資源。
8. 在容器能把服務中的過濾器實例移除之前,容器必須先調用過濾器的 destroy 方法以便過濾器釋放資源
並執行其他的清理工作。
過濾器(Filter)