Filter : 過濾請求和響應

filter對象能夠改變請求和響應的頭信息和內容信息。過濾器和web組件的不一樣之處在於,過濾器一般不會自行建立響應。做爲替代,過濾器提供附加到任意類型的web資源的功能。所以,過濾器不應對要過濾的web資源有任何依賴。這樣,它能夠由多種web資源組成。
過濾器能夠執行的主要任務以下:java

  • 查詢請求並採起響應措施
  • 組織請求-響應對的進一步傳遞
  • 修改請求頭和數據。你能夠經過設置請求的自定義版原本完成此操做。
  • 修改響應頭和數據。你能夠經過設置響應的自定義版原本完成此操做。
  • 與web資源相互做用

應用程序的過濾器包含認證、日誌、圖片轉換、數據壓縮、數據加密、標記流、xml轉換等。
你能夠給一個web資源配置0-多個過濾器,而且能夠自定義過濾器的順序。過濾器鏈在包含此組件的web資源部署時指定,而且在web容器加載的時候實例化。web

編寫filter程序

filtering api定義在javax.servlet包中的Filter, FilterChain, and FilterConfig接口中。你能夠經過實現Filter接口定義一個過濾器。
使用@WebFilter註解在web程序中定義過濾器。這個註解做用在類上,而且包含過濾器的元數據。過濾器註解必須定義至少一個url匹配,經過使用z註解的urlPatterns或value屬性完成這個操做。全部其餘的屬性都是可選的,有默認設置。當只有一個url規則時使用value註解;當有多個url規則或須要自定義屬性時使用urlPatterns註解。
使用@WebFilter 註解的類必須實現 javax.servlet.Filter 接口。
要將配置數據添加到過濾器中,可使用@WebFilter註解的initParams屬性。initParams屬性包含一個 @WebInitParam 註解。下面的代碼片斷定義了一個過濾器,定義了一個初始化參數:api

import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

@WebFilter(filterName = "TimeOfDayFilter",
urlPatterns = {"/*"},
initParams = {
    @WebInitParam(name = "mood", value = "awake")})
public class TimeOfDayFilter implements Filter {
    ...

Filter接口的最重要的方法是doFilter,這個方法能夠執行下列操做:app

  • 覈查請求頭
  • 定製請求對象,若是過濾器想要修改請求頭或數據
  • 定製響應對象,若是過濾器想要修改響應頭或數據
  • 調用過濾器鏈的下一個實體。若是當前過濾器是過濾器鏈的最後一個過濾器,而且結束目標是web資源或靜態資源,下一個實體是鏈末端的資源;不然,下一個實體是war定義的過濾器。過濾器經過調用chain對象的doFilter方法調用下一個實體,傳入調用它的請求、響應或它建立的包裝版本。換種說法是,filter能夠經過不調用下一個實體來阻塞請求。在後一種狀況下,過濾器負責填充響應。
  • 在調用下一個實體後覈查響應頭
  • 拋出一個錯誤指示執行流程中的錯誤

執行doFilter,你必須實現init和destroy方法。init方法在web容器實例化的時候調用;若是你想給filter傳入初始化參數,能夠經過傳入init方法的FilterConfig參數獲取它們。異步

編寫自定義請求和響應代碼

過濾器有多種方式去修改請求和響應。例如,一個過濾器能夠向請求添加一個參數或者在響應中插入數據。
過濾器修改響應必須在響應返回客戶端以前捕獲響應。爲此, 您將一個替代流傳遞給生成響應的servlet。備用流阻止servlet在完成時關閉原始響應流,並容許過濾器修改servlet的響應。
要將此替換流傳遞給servlet,過濾器會建立一個響應包裝器,它會覆蓋getWriter或getOutputStream方法以返回此替換流。這個包裝器經過過濾器鏈doFilter方法傳遞。包裝器方法默認調用包裝的請求或響應對象。
重寫請求方法,你包裝的請求必須繼承ServletRequestWrapper或HttpServletRequestWrapper。重寫響應方法,你的響應必須繼承ServletResponseWrapper or HttpServletResponseWrapper。async

指定過濾器映射

web容器使用請求映射決定給web資源應用具體的過濾器。過濾器映射使用名稱映射一個過濾器到web組件或者使用url規則匹配到web資源。過濾器按照war中定義的順序執行。您可使用NetBeans IDE或使用XML手動編寫列表來爲其部署描述符中的WAR指定過濾器映射列表。
若是你想記錄每個到web應用的請求,你能夠將過濾器映射到url規則「/」。
能夠映射filter到一個或多個web資源,固然你也能夠給一個web資源映射多個filter。參見下圖,F1映射到S一、S二、S3,F2映射到S2,F3映射到S一、S2.

再次強調,filter chain是傳入filter的doFilter方法的一個參數。該鏈經過過濾器映射間接生成。鏈中的過濾器順序與過濾器映射在Web應用程序部署描述符中的顯示順序相同。當一個過濾器映射到S1,web容器調用F1的doFilter方法。S1的過濾器鏈中每一個過濾器的doFilter方法由鏈中的前一個過濾器經過chain.doFilter方法調用。由於S1的過濾器鏈包含過濾器F1和F3,因此F1對chain.doFilter的調用會調用過濾器F3的doFilter方法。 當F3的doFilter方法完成時,控制返回F1的doFilter方法。加密

經過NetBeans IDE定義請求映射

  1. 在Project節點展開應用程序
  2. 展開Project節點下的Web Pages and WEB-INF節點
  3. 雙擊web.xml
  4. 點擊編輯窗口最上方的Filters
  5. 展開編輯窗口的Servlet Filters節點
  6. 點擊Add Filter Element 添加filter與web資源的url映射關係
  7. 在添加servlet filter接口,填寫filtername
  8. 點擊Browse定位filter適用的servlet
  9. 點擊ok
  10. 要約束過濾器應用於請求的方式,步驟以下:

a. 展開Filter Mappings節點
b. 從filterlist中選擇一個filter
c. 點擊add
d. 在添加映射彈窗,須要選擇一個轉發類型:url

  • REQUEST:只映射直接從客戶端過來的請求
  • ASYNC:只映射直接從客戶端過來的的異步async請求
  • FORWARD:只有當請求被轉發到組件時
  • INCLUDE : 僅當請求由已包含的組件處理時
  • ERROR:僅在使用錯誤頁面機制處理請求時

經過選擇多個調度程序類型,能夠指示過濾器應用於上述狀況的任意組合。 若是未指定類型,則默認選項爲REQUESTspa

相關文章
相關標籤/搜索