天天看點

[Servlet&JSP] 過濾器的使用過濾器的概念過濾器的實作

過濾器介于servlet之前,可攔截過濾浏覽器對servlet的請求,也可以改變servlet對浏覽器的響應。

像性能測量、使用者驗證、字元替換、壓縮等需求,應該設計為獨立的元件,随時可以添加到應用程式之中,也可以随時移除,而不用修改原有的程式。servlet/jsp提供了過濾器機制以實作這些元件服務,可視需求抽換過濾器或調整過濾器的順序,也可以針對不同的url應用不同的過濾器,甚至在不同的servlet間請求轉發或包括時應用過濾器。

在servlet/jsp中要實作過濾器,必須實作filter接口,并在web.xml中定義過濾器,讓容器知道該加載哪些過濾器類。filter接口有三個要實作的方法:

<code>init()</code>

<code>dofilter()</code>

<code>destroy()</code>

如果調用了filterchain的<code>dofilter()</code>方法,就會執行下一個過濾器,如果沒有過濾器,就調用請求目标servlet的<code>service()</code>方法。如果因為某個情況(如使用者沒有通過驗證)而沒有調用filterchain的<code>dofilter()</code>方法,則請求就不會繼續交給接下來的過濾器或目标servlet,這時就是所謂的攔截請求(從servlet的觀點來看,它根本不知道浏覽器發出了請求)。

以下實作一個簡單的 性能測量過濾器,以記錄請求與響應間的時間差,并了解servlet處理請求到響應所需花費的時間。

performancefilter.java:

web.xml中的設定:

在web.xml中 ,<code>&lt;/filter-mapping&gt;</code>可以使用<code>&lt;url-pattern&gt;</code>或者<code>&lt;servlet-name&gt;</code>來表示哪些url或servlet将應用此過濾器。如果想一次符合所有的servlet名稱,則可以使用星号(<code>*</code>)。

如果在過濾器初始化時想要讀取一些參數,則可以在<code>&lt;filter&gt;</code>标簽中進行設定,如:

接着在init()方法中可以使用如下語句獲得初始參數值:

觸發過濾器的時機,預設是浏覽器直接送出請求。如果是那些通過<code>requestdispatcher</code>的<code>forward()</code>或<code>include()</code>而來的請求,則可以在<code>web.xml</code>中設定<code>&lt;dispatcher&gt;</code>标簽,指定那些請求轉發類型可以通過過濾器。如果不設定<code>&lt;dispatcher&gt;</code>标簽,則預設為<code>request</code>。<code>error</code>是指由容器處理異常而轉發過來的請求可以觸發過濾器。

如果有某個url或者servlet會應用多個過濾器,則根據<code>&lt;filter-mapping&gt;</code>在web.xml中出現的先後順序,來決定觸發器的執行順序。