天天看點

Filter描述

看到一篇寫filter很好的文章,轉載一下:

<a target="_blank" href="http://tianweili.github.io/blog/2015/01/26/java-filter/">http://tianweili.github.io/blog/2015/01/26/java-filter/</a>

以下文字全部複制于上面連結。

本文主要詳細介紹了filter的以下幾個方面内容:

filter概念介紹

filter的用途

如何借助filter實作攔截功能

filter的開發步驟和配置詳解

filter鍊

filter的生命周期

filter的使用案例

使用filter驗證使用者登入安全控制

防止中文亂碼過濾器

spring+hibernate的opensessioninviewfilter控制session的開關

struts2的web.xml配置

filter也稱之為過濾器,它是servlet技術中最實用的技術,web開發人員通過filter技術,對web伺服器管理的所有web資源:例如jsp, servlet, 靜态圖檔檔案或靜态 html 檔案等進行攔截,進而實作一些特殊的功能。例如實作url級别的權限通路控制、過濾敏感詞彙、壓縮響應資訊等一些進階功能。

它主要用于對使用者請求進行預處理,也可以對httpservletresponse 進行後處理。使用filter 的完整流程:filter 對使用者請求進行預處理,接着将請求交給servlet 進行處理并生成響應,最後filter 再對伺服器響應進行後處理。

在httpservletrequest 到達 servlet 之前,攔截客戶的 httpservletrequest 。根據需要檢查 httpservletrequest ,也可以修改httpservletrequest 頭和資料。

在httpservletresponse 到達用戶端之前,攔截httpservletresponse 。根據需要檢查 httpservletresponse ,也可以修改httpservletresponse頭和資料。

filter接口中有一個dofilter方法,當開發人員編寫好filter,并配置對哪個web資源進行攔截後,web伺服器每次在調用web資源的service方法之前,都會先調用一下filter的dofilter方法,是以,在該方法内編寫代碼可達到如下目的:

調用目标資源之前,讓一段代碼執行。

是否調用目标資源(即是否讓使用者通路web資源)。

web伺服器在調用dofilter方法時,會傳遞一個filterchain對象進來,filterchain對象是filter接口中最重要的一個對象,它也提供了一個dofilter方法,開發人員可以根據需求決定是否調用此方法,調用該方法,則web伺服器就會調用web資源的service方法,即web資源就會被通路,否則web資源不會被通路。

編寫java類實作filter接口,并實作其dofilter方法。

在 web.xml 檔案中使用和元素對編寫的filter類進行注冊,并設定它所能攔截的資源。

web.xml配置各節點介紹:

<code>&lt;filter&gt;</code>指定一個過濾器。

<code>&lt;filter-name&gt;</code>用于為過濾器指定一個名字,該元素的内容不能為空。

<code>&lt;filter-class&gt;</code>元素用于指定過濾器的完整的限定類名。

<code>&lt;init-param&gt;</code>元素用于為過濾器指定初始化參數,它的子元素<code>&lt;param-name&gt;</code>指定參數的名字,<code>&lt;param-value&gt;</code>指定參數的值。

在過濾器中,可以使用<code>filterconfig</code>接口對象來通路初始化參數。

<code>&lt;filter-mapping&gt;</code>元素用于設定一個

filter 所負責攔截的資源。一個filter攔截的資源可通過兩種方式來指定:servlet 名稱和資源通路的請求路徑

<code>&lt;filter-name&gt;</code>子元素用于設定filter的注冊名稱。該值必須是在<code>&lt;filter&gt;</code>元素中聲明過的過濾器的名字

<code>&lt;url-pattern&gt;</code>設定

filter 所攔截的請求路徑(過濾器關聯的url樣式)

<code>&lt;servlet-name&gt;</code>指定過濾器所攔截的servlet名稱。

<code>&lt;dispatcher&gt;</code>指定過濾器所攔截的資源被

servlet 容器調用的方式,可以是<code>request</code>,<code>include</code>,<code>forward</code>和<code>error</code>之一,預設<code>request</code>。使用者可以設定多個<code>&lt;dispatcher&gt;</code>子元素用來指定

filter 對資源的多種調用方式進行攔截。

<code>&lt;dispatcher&gt;</code>子元素可以設定的值及其意義

<code>request</code>:當使用者直接通路頁面時,web容器将會調用過濾器。如果目标資源是通過requestdispatcher的include()或forward()方法通路時,那麼該過濾器就不會被調用。

<code>include</code>:如果目标資源是通過requestdispatcher的include()方法通路時,那麼該過濾器将被調用。除此之外,該過濾器不會被調用。

<code>forward</code>:如果目标資源是通過requestdispatcher的forward()方法通路時,那麼該過濾器将被調用,除此之外,該過濾器不會被調用。

<code>error</code>:如果目标資源是通過聲明式異常處理機制調用時,那麼該過濾器将被調用。除此之外,過濾器不會被調用。

在一個web應用中,可以開發編寫多個filter,這些filter組合起來稱之為一個filter鍊。

web伺服器根據filter在web.xml檔案中的注冊順序,決定先調用哪個filter,當第一個filter的dofilter方法被調用時,web伺服器會建立一個代表filter鍊的filterchain對象傳遞給該方法。在dofilter方法中,開發人員如果調用了filterchain對象的dofilter方法,則web伺服器會檢查filterchain對象中是否還有filter,如果有,則調用第2個filter,如果沒有,則調用目标資源。

和我們編寫的servlet程式一樣,filter的建立和銷毀由web伺服器負責。 web 應用程式啟動時,web 伺服器将建立filter 的執行個體對象,并調用其init方法,讀取web.xml配置,完成對象的初始化功能,進而為後續的使用者請求作好攔截的準備工作(filter對象隻會建立一次,init方法也隻會執行一次)。開發人員通過init方法的參數,可獲得代表目前filter配置資訊的filterconfig對象。

這個方法完成實際的過濾操作。當客戶請求通路與過濾器關聯的url的時候,servlet過濾器将先執行dofilter方法。filterchain參數用于通路後續過濾器。

filter對象建立後會駐留在記憶體,當web應用移除或伺服器停止時才銷毀。在web容器解除安裝 filter 對象之前被調用。該方法在filter的生命周期中僅執行一次。在這個方法中,可以釋放過濾器使用的資源。

使用者在配置filter時,可以使用為filter配置一些初始化參數,當web容器執行個體化filter對象,調用其init方法時,會把封裝了filter初始化參數的filterconfig對象傳遞進來。是以開發人員在編寫filter時,通過filterconfig對象的方法,就可獲得以下内容:

前段時間參與維護一個項目,使用者退出系統後,再去位址欄通路曆史,根據url,仍然能夠進入系統響應頁面。我去檢查一下發現對請求未進行過濾驗證使用者登入。添加一個filter搞定問題!

先在web.xml配置

web.xml

接着編寫filterservlet:

filterservlet.java

這樣既可完成對使用者所有請求,均要經過這個filter進行驗證使用者登入。

項目使用spring架構時。目前台jsp頁面和java代碼中使用了不同的字元集進行編碼的時候就會出現表單送出的資料或者上傳/下載下傳中文名稱檔案出現亂碼的問題,那就可以使用這個過濾器。

當hibernate+spring配合使用的時候,如果設定了lazy=true(延遲加載),那麼在讀取資料的時候,當讀取了父資料後,hibernate 會自動關閉session,這樣,當要使用與之關聯資料、子資料的時候,系統會抛出lazyinit的錯誤,這時就需要使用spring提供的opensessioninviewfilter過濾器。

opensessioninviewfilter主要是保持session狀态直到request将全部頁面發送到用戶端,直到請求結束後才關閉session,這樣就可以解決延遲加載帶來的問題。

注意:opensessioninviewfilter配置要寫在struts2的配置前面。因為tomcat容器在加載過濾器的時候是按照順序加載的,如果配置檔案先寫的是struts2的過濾器配置,然後才是opensessioninviewfilter過濾器配置,是以加載的順序導緻,action在獲得資料的時候session并沒有被spring管理。

項目中使用struts2同樣需要在web.xml配置過濾器,用來截取請求,轉到struts2的action進行處理。

注意:如果在2.1.3以前的struts2版本,過濾器使用org.apache.struts2.dispatcher.filterdispatcher。否則使用org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter。從struts2.1.3開始,将廢棄actioncontextcleanup過濾器,而在strutsprepareandexecutefilter過濾器中包含相應的功能。

三個初始化參數配置:

config參數:指定要加載的配置檔案。逗号分割。

actionpackages參數:指定action類所在的包空間。逗号分割。

configproviders參數:自定義配置檔案提供者,需要實作configurationprovider接口類。逗号分割。