Servlet 編寫過濾器
Servlet 過濾器可以動態地攔截請求和響應,以變換或使用包含在請求或響應中的信息。可以將一個或多個 Servlet 過濾器附加到一個 Servlet 或一組 Servlet。Servlet 過濾器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 頁面。調用 Servlet 前調用所有附加的 Servlet 過濾器。
Servlet 過濾器用途
- 在客戶端的請求訪問后端資源之前,攔截這些請求。
- 在服務器的響應發送回客戶端之前,處理這些響應。
使用說明
當 Web 容器啟動 Web 應用程序時,它會為您在部署描述符中聲明的每一個過濾器創建一個實例。Filter 的執行順序與在web.xml配置文件中的配置順序一致,一般把 Filter 配置在所有的 Servlet 之前。
Servlet 過濾器方法
過濾器是一個實現了 javax.servlet.Filter 接口的 Java 類。javax.servlet.Filter 接口定義了三個方法:
public void doFilter (ServletRequest, ServletResponse, FilterChain)
: 該方法完成實際的過濾操作,當客戶端請求方法與過濾器設置匹配的URL時,Servlet容器將先調用過濾器的doFilter方法。FilterChain 用戶訪問后續過濾器public void init(FilterConfig filterConfig)
: web 應用程序啟動時,web 服務器將創建Filter 的實例對象,並調用其init方法,讀取web.xml配置,完成對象的初始化功能,從而為后續的用戶請求作好攔截的准備工作(filter對象只會創建一次,init方法也只會執行一次)。開發人員通過init方法的參數,可獲得代表當前 filter 配置信息的 FilterConfig 對象public void destroy()
: Servlet容器在銷毀過濾器實例前調用該方法,在該方法中釋放Servlet過濾器占用的資源
流程
請求 --> 匹配過濾器 --> doFilter() --> servlet響應前的過濾 --> chain鏈(servlet響應) --> servlet響應后的過濾
FilterConfig
Filter 的 init 方法中提供了一個 FilterConfig 對象。
注解方式配置 FilterConfig:
1 @WebFilter( 2 filterName = "loginFilter", 3 urlPatterns = "/*", 4 initParams = { 5 @WebInitParam(name = "loginUI", value = "/home/loginUI"), 6 @WebInitParam(name = "loginProcess", value = "home/login"), 7 @WebInitParam(name = "encoding", value = "utf-8") 8 } 9 )
web.xml 文件配置 FilterConfig:
1 <filter> 2 <filter-name>LogFilter</filter-name> 3 <filter-class>com.xxx.test.LogFilter</filter-class> 4 <init-param> 5 <param-name>site</param-name> 6 <param-value>知乎</param-value> 7 </init-param> 8 </filter>
在 init 方法使用 FilterConfig 對象獲取參數:
1 public void init(FilterConfig config) throws ServletException { 2 // 獲取初始化參數 3 String site = config.getInitParameter("Site"); 4 // 輸出初始化參數 5 System.out.println("網站名稱: " + site); 6 }
web.xml配置各節點說明
<filter>
: 指定一個過濾器。<filter-name>
: 用於為過濾器指定一個名字,該元素的內容不能為空。<filter-class>
: 元素用於指定過濾器的完整的限定類名<init-param>
: 元素用於為過濾器指定初始化參數,它的子元素<param-name>
指定參數的名字,<param-value>
指定參數的值。在過濾器中,可以使用 FilterConfig 接口對象來訪問初始化參數<filter-mapping>
: 元素用於設置一個 Filter 所負責攔截的資源。一個 Filter 攔截的資源可通過兩種方式來指定:Servlet 名稱和資源訪問的請求路徑<filter-name>
: 子元素用於設置filter的注冊名稱。該值必須是在<filter>
元素中聲明過的過濾器的名字<url-pattern>
: 設置 filter 所攔截的請求路徑(過濾器關聯的URL樣式)<servlet-name>
: 指定過濾器所攔截的Servlet名稱<dispatcher>
: 指定過濾器所攔截的資源被 Servlet 容器調用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默認REQUEST。用戶可以設置多個子元素用來指定 Filter 對資源的多種調用方式進行攔截。
Servlet 異常處理
當一個 Servlet 拋出一個異常時,Web 容器在使用了 exception-type 元素的 web.xml 中搜索與拋出異常類型相匹配的配置。web.xml 中使用 error-page 元素來指定對特定異常 或 HTTP 狀態碼 作出相應的 Servlet 調用。
web.xml 配置
假設,有一個 ErrorHandler 的 Servlet 在任何已定義的異常或錯誤出現時被調用。以下將是在 web.xml 中創建的項。
1 <!-- servlet 定義 --> 2 <servlet> 3 <servlet-name>ErrorHandler</servlet-name> 4 <servlet-class>ErrorHandler</servlet-class> 5 </servlet> 6 <!-- servlet 映射 --> 7 <servlet-mapping> 8 <servlet-name>ErrorHandler</servlet-name> 9 <url-pattern>/ErrorHandler</url-pattern> 10 </servlet-mapping> 11 12 <!-- error-code 相關的錯誤頁面 --> 13 <error-page> 14 <error-code>404</error-code> 15 <location>/ErrorHandler</location> 16 </error-page> 17 <error-page> 18 <error-code>403</error-code> 19 <location>/ErrorHandler</location> 20 </error-page> 21 22 <!-- exception-type 相關的錯誤頁面 --> 23 <error-page> 24 <exception-type>javax.servlet.ServletException</exception-type > 25 <location>/ErrorHandler</location> 26 </error-page> 27 <error-page> 28 <exception-type>java.io.IOException</exception-type > 29 <location>/ErrorHandler</location> 30 </error-page>
如果您想對所有的異常有一個通用的錯誤處理程序,那么應該定義下面的 error-page,而不是為每個異常定義單獨的 error-page 元素:
1 <error-page> 2 <exception-type>java.lang.Throwable</exception-type > 3 <location>/ErrorHandler</location> 4 </error-page>