1. 程式人生 > >Servlet過濾器----Filter

Servlet過濾器----Filter

JavaEE的Servlet規範描述了三種技術:Servlet,Filter,Listener

(一)過濾器簡介

Filter也稱之為過濾器,它是Servlet技術中最實用的技術,WEB開發人員通過Filter技術,對web伺服器管理的所有web資源:例如Jsp, Servlet, 靜態圖片檔案或靜態 html 檔案等進行攔截,從而實現一些特殊的功能。例如實現URL級別的許可權訪問控制、過濾敏感詞彙、壓縮響應資訊等一些高階功能。

作用總結:對伺服器web資源進行攔截(許可權控制,通過攔截資源進行許可權控制,是否可以訪問)

Servlet API中提供了一個Filter介面,開發web應用時,如果編寫的Java類實現了這個介面,則把這個java類稱之為過濾器Filter。通過Filter技術,開發人員可以實現使用者在訪問某個目標資源之前,對訪問的請求和響應進行攔截,如下所示:

這裡寫圖片描述

這裡寫圖片描述

過濾器攔截對目標資源的訪問(HTTP請求)和伺服器的HTTP響應
過濾器攔截的本質是對URL訪問的攔截(因為資源通過URL進行標識)

(二)過濾器原理

Filter介面中定義了三個方法:init(初始化),doFilter(執行過濾),destory(銷燬)

doFilter方法
Filter介面中有一個doFilter方法,當開發人員編寫好Filter,並配置對哪個web資源(攔截url)進行攔截後,WEB伺服器每次在呼叫web資源之前,都會先呼叫一下filter的doFilter方法,因此,在該方法內編寫程式碼可達到如下目的:

  • 呼叫目標資源之前,讓一段程式碼執行
  • 是否呼叫目標資源(即是否讓使用者訪問web資源)。
    呼叫目標資源之後,讓一段程式碼執行
    • web伺服器在呼叫doFilter方法時,會傳遞一個filterChain物件進來,filterChain物件是filter介面中最重要的一個物件,它也提供了一個doFilter方法,開發人員可以根據需求決定是否呼叫此方法,呼叫該方法,則web伺服器就會呼叫web資源的service方法,即web資源就會被訪問,否則web資源不會被訪問。

Filter的doFilter方法中,傳入FilterChain引數,FilterChain請求呼叫鏈,提供doFilter用於執行呼叫鏈下一個資源

(三)第一個Filter例項

Filter的編寫其實與Servlet的編寫流程十分相像(Servlet的編寫見http://blog.csdn.net/megustas_jjc/article/details/53164394),Filter的編寫步驟如下:

假設現有一個JSP頁面:

  • (1)編寫類實現(繼承)Filter介面 (實現Filter介面 init doFilter destroy )
  • (2)在web.xml中註冊過濾器(為過濾器定義一個name,同servlet一樣,那麼可以隨意選取),配置Filter攔截哪個web資源

在啟動伺服器時,Filter物件被建立,執行過濾器init 方法
配置攔截後,訪問hello.jsp — 過濾器中doFilter方法獲得執行(每請求一次,doFilter 過濾一次)

  • 沒有配置過濾器之前,直接訪問hello.jsp,當配置過濾器後,過濾器先於hello.jsp執行 - - - - - 此時過濾器Filter1和hello.jsp組成請求呼叫鏈FilterChain(就是這條鏈上有多少個請求訪問資源)

如果想要訪問請求呼叫鏈上的下一個資源

攔截目標資源後,如果想目標資源執行: chain.doFilter ;如果不執行chain.doFilter 目標資源不會得到執行

destroy方法和Servlet的destroy 一樣,在正常關閉伺服器情況下執行

(四)Filter鏈

  • 在一個web應用中,可以開發編寫多個Filter,這些Filter組合起來稱之為一個Filter鏈。對同一web資源配置多個過濾器,例如,我們再定義一個過濾器Filter2,那麼web.xml的配置如下:

當配置多個Filter 攔截hello.jsp 組成新的請求呼叫鏈 Filter1 — Filter2 — hello.jsp過濾器鏈會根據mapping 的順序組成 順序呼叫過濾器執行

(五)Filter生命週期

1.init(FilterConfig filterConfig)throws ServletException:

  • 和我們編寫的Servlet程式一樣,Filter的建立和銷燬由WEB伺服器負責。 web 應用程式啟動時,web 伺服器將建立Filter 的例項物件,並呼叫其init方法進行初始化(注:filter物件只會建立一次,init方法也只會執行一次。)
  • 開發人員通過init方法的引數,可獲得代表當前filter配置資訊的FilterConfig物件

FilterConfig
使用者在配置filter時,可以使用為filter**配置一些初始化引數,當web容器例項化Filter物件,呼叫其init方法時,會把封裝了filter初始化引數的FilterConfig物件傳遞進來**。因此開發人員在編寫filter時,通過FilterConfig物件的方法,就可獲得(FileConfig 作用和ServletConfig 類似—- 為過濾器提供初始化引數):

  • :得到Filter的名稱
  • :返回指定名稱的初始化引數的值,如果不存在,則返回null。
  • :返回過濾器所有初始化引數的名字的列舉集合。
  • :返回Servlet上下文物件的引用(獲得ServletContext物件 儲存全域性資料、讀取web資原始檔)。

例如,如下進行初始化引數配置

例如在WEB-INF中建立檔案:

這裡寫圖片描述

通過FilterConfig獲得資訊:

2.doFilter(ServletRequest,ServletResponse,FilterChain):

  • 每次filter進行攔截都會執行
  • 在實際開發中方法中引數request和response通常轉換為HttpServletRequest和HttpServletResponse型別進行操作

3.destroy():

  • 在Web容器解除安裝 Filter 物件之前被呼叫(伺服器被正常關閉)。

(六)Filter對映

(1)一個web資源配置多個過濾器:上面例子

(2)一個過濾器配置多個web資源

元素用於設定一個 Filter 所負責攔截的資源。一個Filter攔截的servlet可通過兩種方式來指定:Servlet 名稱資源訪問的請求路徑
注意:如下,過濾servlet可以通過路徑/hello或者通過servlet的名字進行過濾是通用的過濾方法,雅思聽力標準是針對於過濾servlet可以使用的

(3)關於url-pattern 寫法和Servlet相同 有三種 完全匹配、目錄匹配、副檔名匹配

(4)標籤及意義(可以配置在什麼情況下,或者說是在什麼呼叫方式下攔截目標資源)

指定過濾器所攔截的資源被 Servlet 容器呼叫的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,預設REQUEST。使用者可以設定多個子元素用來指定 Filter 對資源的多種呼叫方式進行攔截。

伺服器呼叫資源的四種方式

這裡寫圖片描述

例如,此時還有一個forword.jsp頁面:

在配置時:

此時直接訪問hello.jsp,由於REQUEST的設定,會執行過濾,同理,直接訪問forward.jsp也會執行過濾(執行doFilter),因為FORWARD在forward轉發時執行過濾(可以同時新增多個對過濾方式進行設定)。

  • REQUEST:當用戶直接訪問頁面時,Web容器將會呼叫過濾器。如果目標資源是通過RequestDispatcher的include()或forward()方法訪問時,那麼該過濾器就不會被呼叫。
  • INCLUDE:如果目標資源是通過RequestDispatcher的include()方法訪問時,那麼該過濾器將被呼叫。除此之外,該過濾器不會被呼叫。
  • FORWARD:如果目標資源是通過RequestDispatcher的forward()方法訪問時,那麼該過濾器將被呼叫,除此之外,該過濾器不會被呼叫。
  • ERROR:如果目標資源是通過宣告式異常處理機制呼叫時,那麼該過濾器將被呼叫。除此之外,過濾器不會被呼叫。

如果想讓過濾器執行,必須滿足過濾方式 !!!! 如果forward、include 、error跳轉時執行過濾 必須配置 dispatcher。