# Servlet 編寫過濾器
Servlet 過濾器是可用于 Servlet 編程的 Java 類,有以下目的:
* 在客戶端的請求訪問后端資源之前,攔截這些請求。
* 在服務器的響應發送回客戶端之前,處理這些響應。
根據規范建議的各種類型的過濾器:
* 身份驗證過濾器(Authentication Filters)。
* 數據壓縮過濾器(Data compression Filters)。
* 加密過濾器(Encryption Filters)。
* 觸發資源訪問事件過濾器。
* 圖像轉換過濾器(Image Conversion Filters)。
* 日志記錄和審核過濾器(Logging and Auditing Filters)。
* MIME-TYPE 鏈過濾器(MIME-TYPE Chain Filters)。
* 標記化過濾器(Tokenizing Filters)。
* XSL/T 過濾器(XSL/T Filters),轉換 XML 內容。
過濾器被部署在部署描述符文件 **web.xml** 中,然后映射到您的應用程序的部署描述符中的 Servlet 名稱或 URL 模式。
當 Web 容器啟動 Web 應用程序時,它會為您在部署描述符中聲明的每一個過濾器創建一個實例。該過濾器執行的順序是按它們在部署描述符中聲明的順序。
## Servlet 過濾器方法
過濾器是一個實現了 javax.servlet.Filter 接口的 Java 類。javax.servlet.Filter 接口定義了三個方法:
| 方法 | 描述 |
| --- | --- |
| **public void doFilter (ServletRequest, ServletResponse, FilterChain)** | 該方法在每次一個請求/響應對因客戶端在鏈的末端請求資源而通過鏈傳遞時由容器調用。 |
| **public void init(FilterConfig filterConfig)** | 該方法由 Web 容器調用,指示一個過濾器被放入服務。 |
| **public void destroy()** | 該方法由 Web 容器調用,指示一個過濾器被取出服務。 |
## Servlet 過濾器實例
以下是 Servlet 過濾器的實例,將輸出客戶端的 IP 地址和當前的日期時間。本實例讓您對 Servlet 過濾器有基本的了解,您可以使用相同的概念編寫更復雜的過濾器應用程序:
```
// 導入必需的 java 庫
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// 實現 Filter 類
public class LogFilter implements Filter {
public void init(FilterConfig config)
throws ServletException{
// 獲取初始化參數
String testParam = config.getInitParameter("test-param");
// 輸出初始化參數
System.out.println("Test Param: " + testParam);
}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws java.io.IOException, ServletException {
// 獲取客戶機的 IP 地址
String ipAddress = request.getRemoteAddr();
// 記錄 IP 地址和當前時間戳
System.out.println("IP "+ ipAddress + ", Time "
+ new Date().toString());
// 把請求傳回過濾鏈
chain.doFilter(request,response);
}
public void destroy( ){
/* 在 Filter 實例被 Web 容器從服務移除之前調用 */
}
}
```
以通常的方式編譯 **LogFilter.java**,把您的類文件放入 <Tomcat-installation-directory>/webapps/ROOT/WEB-INF/classes 中。
## Web.xml 中的 Servlet 過濾器映射(Servlet Filter Mapping)
定義過濾器,然后映射到一個 URL 或 Servlet,這與定義 Servlet,然后映射到一個 URL 模式方式大致相同。在部署描述符文件 **web.xml** 中為 filter 標簽創建下面的條目:
```
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
```
上述過濾器適用于所有的 Servlet,因為我們在配置中指定 **/*** 。如果您只想在少數的 Servlet 上應用過濾器,您可以指定一個特定的 Servlet 路徑。
現在試著以常用的方式調用任何 Servlet,您將會看到在 Web 服務器中生成的日志。您也可以使用 Log4J 記錄器來把上面的日志記錄到一個單獨的文件中。
## 使用多個過濾器
Web 應用程序可以根據特定的目的定義若干個不同的過濾器。假設您定義了兩個過濾器 _AuthenFilter_ 和 _LogFilter_。您需要創建一個如下所述的不同的映射,其余的處理與上述所講解的大致相同:
```
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter>
<filter-name>AuthenFilter</filter-name>
<filter-class>AuthenFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
```
## 過濾器的應用順序
web.xml 中的 filter-mapping 元素的順序決定了 Web 容器應用過濾器到 Servlet 的順序。若要反轉過濾器的順序,您只需要在 web.xml 文件中反轉 filter-mapping 元素即可。
例如,上面的實例將先應用 LogFilter,然后再應用 AuthenFilter,但是下面的實例將顛倒這個順序:
```
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
```
- Java 基礎
- Java 簡介
- Java開發環境配置
- Java基礎語法
- Java對象和類
- Java基本數據類型
- Java變量類型
- Java修飾符
- Java運算符
- Java循環結構 - for, while 及 do...while
- Java分支結構 - if...else/switch
- Java Number類
- Java Character類
- Java String類
- Java StringBuffer和StringBuilder類
- Java 數組
- Java 日期時間
- Java正則表達式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 異常處理
- Java 面向對象
- Java 繼承
- Java 重寫(Override)與重載(Overload)
- Java 多態
- Java 抽象類
- Java 接口
- Java 包(package)
- Java 高級教程
- Java 數據結構
- Java Enumeration接口
- Java Bitset類
- Java Vector 類
- Java Stack 類
- Java Dictionary 類
- Java Hashtable 接口
- Java Properties 接口
- Java 集合框架
- Java 泛型
- Java序列化
- Java 網絡編程
- Java 發送郵件
- Java 多線程編程
- Java Applet基礎
- Java 文檔注釋
- Servlet 教程
- Servlet 簡介
- Servlet 環境設置
- Servlet 生命周期
- Servlet 實例
- Servlet 表單數據
- Servlet 客戶端 HTTP 請求
- Servlet 服務器 HTTP 響應
- Servlet HTTP 狀態碼
- Servlet 編寫過濾器
- Servlet 異常處理
- Servlet Cookies 處理
- Servlet Session 跟蹤
- Servlet 數據庫訪問
- Servlet 文件上傳
- Servlet 處理日期
- Servlet 網頁重定向
- Servlet 點擊計數器
- Servlet 自動刷新頁面
- Servlet 發送電子郵件
- Servlet 包
- Servlet 調試
- Servlet 國際化
- JSP 基礎
- JSP 簡介
- JSP 開發環境搭建
- JSP 結構
- JSP 生命周期
- JSP 語法
- JSP 指令
- JSP 動作元素
- JSP 動作元素
- JSP 隱含對象
- JSP 客戶端請求
- JSP 服務器響應
- JSP HTTP 狀態碼
- JSP 表單處理
- JSP 過濾器
- JSP Cookies 處理
- JSP Session
- JSP 文件上傳
- JSP 日期處理
- JSP 頁面重定向
- JSP 點擊量統計
- JSP 自動刷新
- JSP 發送郵件
- JSP 高級教程
- JSP 標準標簽庫(JSTL)
- JSP 連接數據庫
- JSP XML 數據處理
- JSP JavaBean
- JSP 自定義標簽
- JSP 表達式語言
- JSP 異常處理
- JSP 調試
- JSP 國際化
- 免責聲明