filter
Servlet規範定義了filter(過濾器),用來截獲WEB應用中對資源的請求,資源包括Servlet、JSP及靜態資源(如HTML或圖片)。過濾器可以檢查和修改請求、響應對象,並可以執行其它任務。過濾器是Servlet的高級功能,當開發人員不能更改現有資源的代碼、但需要修改該資源的行爲時,過濾器非常有用。過濾器最常用來實現的功能有:
1. 日誌和審計
2. 安全認證
3. 圖片轉換
4. 數據壓縮
5. 編碼格式轉換
6. 加密
在WEB應用中定義過濾器之後,過濾器會截獲特定資源(基於URL模式)的請求,並執行過濾器中的代碼。可以爲每個或每組資源指定單個過濾器,也可以指定多個按特定順序調用的過濾器鏈。
截獲請求後,過濾器可以訪問爲HTTP請求和響應提供訪問權的javax.servlet.ServletRequest和javax.servlet.ServletResponse對象,以及javax.servlet.FilterChain對象。FilterChain對象包含可以按順序調用的過濾器列表。過濾器完成工作後,可以調用鏈中的下一個過濾器,直至控制權傳遞至鏈中最後一個過濾器,訪問原始資源。此時過濾器可以檢查和修改響應頭和數據,阻塞請求,並在過濾器鏈中以反向順序調用過濾器,最終將響應返回給客戶端。
過濾器類必須實現javax.servlet.Filter接口,並實現該接口的下列方法:
2. doFilter()
可以實現請求、響應對象的檢查和修改,並執行日誌記錄等其它任務、調用鏈中下一個過濾器。
Servlet 3.0規範可以使用註解@WebFilter來定義過濾器,使用註解@WebFilter標註的類必須實現javax.servlet.Filter接口。下面的代碼片段定義了一個截獲URL模式爲/mail/*的請求的過濾器:
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
@WebFilter("/mail/*")
public class LogFilter implements Filter {
使用註解@WebFilter可以省掉在web.xml(web-fragment.xml)中配置過濾器。如果一個過濾器的實現類被標註了註解@WebFilter,同時也在web.xml(web-fragment.xml)中配置了該過濾器,則web.xml(web-fragment.xml)中的配置優先。註解@WebFilter的常用配置屬性如下:
表2‑7 註解@WebFilter的常用配置
屬性 |
用途 |
默認值 |
filterName |
指定過濾器的名稱 |
“” |
value |
指定過濾器截獲請求的URL模式,等同於urlPatterns |
{} |
urlPatterns |
指定過濾器截獲請求的URL模式 |
{} |
servletNames |
指定過濾器應用於哪些Servlet,Servlet名稱應同@WebServlet和web.xml(web-fragment.xml)中配置的一致 |
{} |
initParams |
指定過濾器的初始化參數 |
{} |
dispatcherTypes |
指定過濾器截獲哪些類型的請求,取值爲以下選項的組合: DispatcherType.FORWARD DispatcherType.INCLUDE DispatcherType.REQUEST DispatcherType.ASYNC DispatcherType.ERROR |
{ DispatcherType .REQUEST} |
asyncSupported |
指定過濾器是否支持異步模式 |
false |
例:
@WebFilter(filterName="logFilter",
urlPatterns="/mail/*",
initParams={@WebInitParam(name="logDir",value="log")})
編寫好過濾器後,可以直接在過濾器的實現類上標註@WebFilter來配置過濾器的名稱和過濾器的截獲請求的URL模式等參數。註解@WebFilter的name屬性定義過濾器的名稱,urlPatterns屬性定義該過濾器截獲請求的URL模式,initParams屬性定義過濾器的初始化參數:
@WebFilter(filterName="logFilter",
urlPatterns="/mail/*",
initParams={@WebInitParam(name="logDir",value="log")})
也可以在web.xml(web-fragment.xml)中配置過濾器,舉例來說:
<!-- 過濾器聲明,聲明過濾器名稱、指定過濾器的Java類和初始化參數 -->
<filter>
<filter-name>logFilter</filter-name>
<filter-class>samples.filter.LogFilter</filter-class>
<init-param>
<param-name>logDir</param-name>
<param-value>log</param-value>
</init-param>
</filter>
<!-- 基於URL模式創建過濾器映射,所有/mail請求都會由logFilter進行過濾 -->
<filter-name>logFilter</filter-name>
<url-pattern>/mail/*</url-pattern>
</filter-mapping>