1. 程式人生 > >Spring web過濾器-各種filter講解

Spring web過濾器-各種filter講解


http://liuluo129.iteye.com/blog/1965268

圖來自上面連線

http://blog.csdn.net/geloin/article/details/7441330

整理於上面

Spring的web包中中有很多過濾器,這些過濾器位於org.springframework.web.filter並且理所當然地實現了javax.servlet.Filter,不過實現的方式有以下幾類:

        (1) 直接實現Filter,這一類過濾器只有CompositeFilter;

        (2) 繼承抽象類GenericFilterBean,該類實現了javax.servlet.Filter,這一類的過濾器只有一個,即DelegatingFilterProxy;

        (3) 繼承抽象類OncePerRequestFilter,該類為GenericFilterBean的直接子類,這一類過濾器包括CharacterEncodingFilter、HiddenHttpMethodFilter、HttpPutFormContentFilter、RequestContextFilter和ShallowEtagHeaderFilter;

        (4) 繼承抽象類AbstractRequestLoggingFilter,該類為OncePerRequestFilter的直接子類,這一類過濾器包括CommonsRequestLoggingFilter、Log4jNestedDiagnosticContextFilter和ServletContextRequestLoggingFilter。

        本文要講述的,即是GenericFilterBean、OncePerRequestFilter和AbstractRequestLoggingFilter。

        GenericFilterBean

        抽象類GenericFilterBean實現了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean五個介面,作用如下:

        (1) Filter,實現過濾器;

        (2) BeanNameAware,實現該介面的setBeanName方法,便於Bean管理器生成Bean;

        (3) EnvironmentAware,實現該介面的setEnvironment方法,指明該Bean執行的環境;

        (4) ServletContextAware,實現該介面的setServletContextAware方法,指明上下文;

        (5) InitializingBean,實現該介面的afterPropertiesSet方法,指明設定屬性生的操作;

        (6) DisposableBean,實現該介面的destroy方法,用於回收資源。

        GenericFilterBean的工作流程是:init-doFilter-destory,其中的init和destory在該類中實現,doFilter在具體實現類中實現。init的程式碼如下:

  1. /** 
  2.      * Standard way of initializing this filter. 
  3.      * Map config parameters onto bean properties of this filter, and 
  4.      * invoke subclass initialization. 
  5.      * @param filterConfig the configuration for this filter 
  6.      * @throws ServletException if bean properties are invalid (or required 
  7.      * properties are missing), or if subclass initialization fails. 
  8.      * @see #initFilterBean 
  9.      */
  10.     publicfinalvoid init(FilterConfig filterConfig) throws ServletException {  
  11.         Assert.notNull(filterConfig, "FilterConfig must not be null");  
  12.         if (logger.isDebugEnabled()) {  
  13.             logger.debug("Initializing filter '" + filterConfig.getFilterName() + "'");  
  14.         }  
  15.         this.filterConfig = filterConfig;  
  16.         // Set bean properties from init parameters.
  17.         try {  
  18.             PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties);  
  19.             BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);  
  20.             ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext());  
  21.             bw.registerCustomEditor(Resource.classnew ResourceEditor(resourceLoader, this.environment));  
  22.             initBeanWrapper(bw);  
  23.             bw.setPropertyValues(pvs, true);  
  24.         }  
  25.         catch (BeansException ex) {  
  26.             String msg = "Failed to set bean properties on filter '" +  
  27.                 filterConfig.getFilterName() + "': " + ex.getMessage();  
  28.             logger.error(msg, ex);  
  29.             thrownew NestedServletException(msg, ex);  
  30.         }  
  31.         // Let subclasses do whatever initialization they like.
  32.         initFilterBean();  
  33.         if (logger.isDebugEnabled()) {  
  34.             logger.debug("Filter '" + filterConfig.getFilterName() + "' configured successfully");  
  35.         }  
  36.     }  

        該方法來自於javax.servlet.Filter,即過濾器的初始化,它的主要工作集中於以下幾行程式碼:
  1. // 從properties檔案中獲取值,這裡是web.xml
  2. PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties);  
  3. // 設定bean介面卡
  4. BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);  
  5. // 設定上下文,這裡的servletContext的設定繼承自ServletContextAware的setter
  6. ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext());  
  7. // 將上下文資訊和環境資訊設定到bean介面卡中,這裡的environment來自於EnvironmentAware的setter
  8. bw.registerCustomEditor(Resource.classnew ResourceEditor(resourceLoader, this.environment));  
  9. // 初始化bean介面卡
  10. initBeanWrapper(bw);  
  11. // 將從properties中獲取的資源放置到bean介面卡
  12. bw.setPropertyValues(pvs, true);  
  13. // 初始化bean
  14. initFilterBean();  

        其中initFilterBean方法在兩個位置起作用,一處是上文所述的init方法,另一處是afterPropertiesSet方法,在呼叫該方法前,需要保證用於Filter的所有的bean都已被設定,該方法由子類實現。

        GenericFilterBean中包含一個內部私有類FilterConfigPropertyValues,主要用於將web.xml中定義的init-param的值取出。

        OncePerRequestFilter

        抽象類oncePerRequestFilter繼承自GenericFilterBean,它保留了GenericFilterBean中的所有方法並對之進行了擴充套件,在oncePerRequestFilter中的主要方法是doFilter,程式碼如下:

  1. /** 
  2.      * This <code>doFilter</code> implementation stores a request attribute for 
  3.      * "already filtered", proceeding without filtering again if the 
  4.      * attribute is already there. 
  5.      * @see #getAlreadyFilteredAttributeName 
  6.      * @see #shouldNotFilter 
  7.      * @see #doFilterInternal 
  8.      */
  9.     publicfinalvoid doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)  
  10.             throws ServletException, IOException {  
  11.         if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {  
  12.             thrownew ServletException("OncePerRequestFilter just supports HTTP requests");  
  13.         }  
  14.         HttpServletRequest httpRequest = (HttpServletRequest) request;  
  15.         HttpServletResponse httpResponse = (HttpServletResponse) response;  
  16.                 // 呼叫GenericFilterBean的getFilterName方法返回已過濾的屬性名
  17.         String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();  
  18.         if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {  
  19.             // 未呼叫該過濾器或已過濾
  20.             filterChain.doFilter(request, response);  
  21.         }  
  22.         else {  
  23.             // 進行過濾
  24.             request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);  
  25.             try {  
  26.                 doFilterInternal(httpRequest, httpResponse, filterChain);  
  27.             }  
  28.             finally {  
  29.                 // Remove the "already filtered" request attribute for this request.
  30.                 request.removeAttribute(alreadyFilteredAttributeName);  
  31.             }  
  32.         }  
  33.     }  

        在doFilter方法中,doFilterInternal方法由子類實現,主要作用是規定過濾的具體方法。

        AbstractRequestLoggingFilter

        AbstractRequestLoggingFilter繼承了OncePerRequestFilter並實現了其doFilterInternal方法,該方法程式碼如下:

  1. /** 
  2.      * Forwards the request to the next filter in the chain and delegates down to the subclasses to perform the actual 
  3.      * request logging both before and after the request is processed. 
  4.      * 
  5.      * @see #beforeRequest 
  6.      * @see #afterRequest 
  7.      */
  8.     @Override
  9.     protectedvoid doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
  10.             throws ServletException, IOException {  
  11.         if (isIncludePayload()) {  
  12.                         // 若日誌中包含負載,則重置request
  13.             request = new RequestCachingRequestWrapper(request);  
  14.         }  
  15.                 // 過濾前執行的方法
  16.         beforeRequest(request, getBeforeMessage(request));  
  17.         try {  
  18.                         // 執行過濾
  19.             filterChain.doFilter(request, response);  
  20.         }  
  21.         finally {  
  22.                         // 過濾後執行的方法
  23.             afterRequest(request, getAfterMessage(request));  
  24.         }  
  25.     }  

        doFilter方法中的beforeRequest和afterRequest方法由子類實現,RequestCachingRequestWrapper為AbstractRequestLoggingFilter的內部內,主要作用是重置request。

        區別

         我們在使用過濾器時,通常沒必要知道GenericFilterBean、OncePerRequestFilter和AbstractRequestLoggingFilter,但不防礙我們瞭解這幾個類,就上文所述,

AbstractRequestLoggingFilter繼承自OncePerRequestFilter

OncePerRequestFilter繼承自GenericFilterBean

所以我們知道,genericFilterBean是任何型別的過濾器的一個比較方便的超類,

這個類主要實現的就是從web.xml檔案中取得init-param中設定的值,然後對Filter進行初始化(當然,其子類可以覆蓋init方法)

OncePerRequestFilter繼承自GenericFilterBean,那麼它自然知道怎麼去獲取配置檔案中的屬性及其值,所以其重點不在於取值,而在於確保在接收到一個request後,每個filter只執行一次它的子類只需要關注Filter的具體實現即doFilterInternal

        AbstractRequestLoggingFilter是對OncePerRequestFilter的擴充套件,它除了遺傳了其父類及祖先類的所有功能外,還在doFilterInternal中決定了在過濾之前和之後執行的事件,它的子類關注的是beforeRequest和afterRequest

        總體來說,這三個類分別執行了Filter的某部分功能,當然,具體如何執行由它們的子類規定,若你需要實現自己的過濾器,也可以根據上文所述繼承你所需要的類

==============================================================================================================

http://blog.csdn.net/geloin/article/details/7443329

 AbstractRequestLoggingFilter類定義了兩個方法beforeRequest和afterRequest分別用於設定過濾前後執行的操作

它有三個子類,

分別是CommonsRequestLoggingFilter、

ServletContextRequestLoggingFilter

和Log4jNestedDiagnosticContextFilter,

這三個子類分別實現了各自的beforeRequest和afterRequest。其中,

CommonsRequestLoggingFilter在過濾前後分別打印出一段debug的資訊;

ServletContextRequestLoggingFilter在過濾前後分別向日志文件中寫入一段日誌資訊,日誌檔案可由log4j.properties等指定;

Log4jNestedDiagnosticContextFilter則將日誌資訊儲存到NDC中,NDC採用了一個類似棧的機制來push和pot上下文資訊,每一個執行緒都獨立地儲存上下文資訊,比如說一個servlet就可以針對 每一個request建立對應的NDC,儲存客戶端地址等資訊。

        當然,在AbstractRequestLoggingFilter中,還包含很多其他方法:

        setIncludeQueryString:查詢語句是否包含在日誌檔案中,true或false;

        setIncludeClientInfo:客戶地址和session id是否包含在日誌中,true或false;

        setIncludePayload:負載資訊是否包含在日誌資訊中,true或false;

        setMaxPayloadLength:最大負載量,int值;

        setBeforeMessagePrefix:日誌資訊前的資訊的字首;

        setBeforeMessageSuffix:日誌資訊前的資訊的字尾;

        setAfterMessagePrefix:日誌資訊後的資訊的字首;

        setAfterMessageSuffix:日誌資訊後的資訊的字尾。

        以上這些資訊均可以在init-param中進行設定。

       日誌資訊在getBeforeMessage和getAfterMessage方法中通過createMessage建立,然後被doFilterInternal呼叫

日誌資訊中至少包含uri資訊,其他資訊則根據init-param中所設定的值獲取

例如,當includeQueryString的值為true時,日誌資訊中除uri資訊外,還包含query string資訊。

       由此可以,在spring中已定義的AbstractRequestLoggingFiter的子類過濾器均是用於輸入上下文資訊,只不過承載的方式不同

其中CommonsRequestLoggingFilter將上下文資訊直接列印

ServletContextRequestLoggingFilter將上下文資訊寫入日誌檔案

Log4jNestedDiagnosticContextFilter將上下文資訊寫入NDC中


==============================================================================================================

http://blog.csdn.net/geloin/article/details/7444321

因為很少有人用到GET和POST以外的method, 而且只有部分瀏覽器不支援部分method put,deletede等

但是為了做到程式相容性更好,spring3.0添加了一個過濾器HiddenHttpMethodFilter,可以將這些請求轉換為標準的http方法,使得支援PUT與DELETE,就像可以使用GET、POST、一樣,

 HiddenHttpMethodFilter的父類是OncePerRequestFilter,它繼承了父類的doFilterInternal方法,工作原理是

將jsp頁面的form表單的method屬性值在doFilterInternal方法中轉化為標準的Http方法,即GET,、POST、 HEAD、OPTIONS、PUT、DELETE、

TRACE,然後到Controller中找到對應的方法。

例如,在使用註解時我們可能會在Controller中用於@RequestMapping(value = "list", method = RequestMethod.PUT),

相關推薦

Spring web過濾器-各種filter講解

http://liuluo129.iteye.com/blog/1965268 圖來自上面連線 http://blog.csdn.net/geloin/article/details/7441330 整理於上面 Spring的web包中中有很多過濾器,這些過濾器

spring過濾器filter)、攔截器(interceptor)和切面(aop)的執行順序

1.程式執行的順序是先進過濾器,再進攔截器,最後進切面。注意:如果攔截器中preHandle方法返回的為false時,則無法進入切面,例子如下 @RestController @RequestMapping("/user") public class UserController {

web 過濾器 FilterSpring 攔截器 interceptor

拋出異常 internal 針對 turn 被調用 enc 過濾 過濾器 文件 1、過濾器(Filter)(在web.xml中註冊過濾器)   首先說一下Filter的使用地方,我們在配置web.xml時,總會配置下面一段設置字符編碼,不然會導致亂碼問題: <

Web.xml中Filter過濾器標簽幾個說明

name 網上 spa 路徑 class 地址 web 例子 -m 在研究liferay框架中看到Web.xml中加入了過濾器的標簽,可以根據頁面提交的URL地址進行過濾,發現有幾個新標簽沒用過,下面就介紹以下幾個過濾器的標簽用法: <!-- 定義Filte

Spring-web原始碼解析之Filter-OncePerRequestFilter

轉自:  http://blog.csdn.net/ktlifeng/article/details/50630934 基於4.1.7.RELEASE 我們先看一個filter-mapping的配置 

Web - 過濾器Filter & 監聽器Listener

一、過濾器Filter filter執行在servlet和jsp之前 , 對客戶端訪問的資源進行過濾.        符合條件放行 , 不符合條件不放行 .(使用FilterChain.doFilter方法放行!)

web過濾器Filter

Filter 過濾器,其實就是對客戶端傳送過來的請求進行過濾。瀏覽器發出,然後伺服器派servlet處理,在中間就可以過濾,起到攔截的作用 作用: 1.對一些敏感詞彙進行過濾 2.統一設定編碼 3.自動登入 … 如何使用Filter 1.定義一個類,實現File

Java EE Web部分--06.Filter過濾器

一、概述 濾器(filter):本質是Java中預先定義好了不同的介面,可以過濾不同的內容,在專案中,我們對訪問某些資源的請求需要進條件的篩選、過濾時、就需要使用者定義一個實現類,然後實現介面中的過濾方法,在方法中書寫過濾的條件。filter是對客戶端訪問資源的過濾,符合條

Spring中在web.xml新增<filter>,處理頁面顯示亂碼問題 模板

<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncod

Spring Boot實戰之Filter實現使用JWT進行介面認證 jwt(json web token) 使用者傳送按照約定,向服務端傳送 Header、Payload 和 Signature,

Spring Boot實戰之Filter實現使用JWT進行介面認證 jwt(json web token) 使用者傳送按照約定,向服務端傳送 Header、Payload 和 Signature,幷包含認證資訊(密碼),驗證通過後服務端返回一個token,之後使用者使用該

web 過濾器(jsp+cookie+filter免登陸Tomcat)使用記錄

注意:過濾器主要過濾request,response裡面的值。 *web.xml---- *登入action新增cookie------- *filter過濾器獲取cookie------ (不用從新輸入使用者名稱,密碼,直接讀取cookie通過查詢資料庫,獲取User 

Spring Web學習--DelegatingFilterProxy 代理Filter

       Spring web在設計的時候考慮到某些功能的實現是通過Filter來攔截進行實現的,如果直接的簡單的實現幾個Filter好像也不是不可以(平時我們就是這麼用的),但是Spring框架最核心的是IOC容器,和Spring框架最好的實現就是將要實現的Filter

Web.xml中Filter過濾器標籤幾個說明

在研究liferay框架中看到Web.xml中加入了過濾器的標籤,可以根據頁面提交的URL地址進行過濾,發現有幾個新標籤沒用過,下面就介紹以下幾個過濾器的標籤用法: <!-- 定義Filter --> <filter> <!-- Filte

三個例項帶你走進web過濾器Filter API

web過濾器   過濾器是指攔截請求,並對傳給被請求資源的ServletRequest或ServletResponse進行處理的一個物件。 過濾器可用於登入、加密和解密、對話檢查、圖片轉換等待。過濾器可以配置攔截一個或者多個資源 1.Filter API 過濾器必須實

Web開發---過濾器Filter

開發人員通過對Filter配置,可以管理所有的web資源,對jsp,servlet,靜態圖片或者靜態html進行攔截。還可以在返回之前進行攔截處理。 一個java類實現了Filter介面,就可以成為一

java web過濾器你瞭解嗎?(Filter和ChainFilter鏈)

1、什麼是過濾器?      在客戶端到伺服器的過程中,當傳送請求時,如果有不符合的資訊將會被filter進行攔截,如果符合則會進行放行,在伺服器給客戶端響應時也會進行判斷 如果有不符合的資訊將會被filter進行攔截,如果符合則會進行放行。     OOP:Java面向物件

SpringMVC的攔截器(Interceptor)和過濾器Filter)的區別與聯系

get err 實例 分享 切面 簡介 () lee XML 一 簡介 (1)過濾器: 依賴於servlet容器。在實現上基於函數回調,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器實例只能在容器初始化時調用一次。使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取

Spring MVC Flash Attribute 的講解與使用示例

取數據 這樣的 src artifact tag osc web.xml startup 刷新 Spring MVC 3.1版本加了一個很有用的特性,Flash屬性,它能解決一個長久以來缺少解決的問題,一個POST/Redirect/GET模式問題。 正常的MVC W

spring web mvc第一天

第一個 solver 運行 tco 調用 角色 servlet ret ack spring web mvc 感覺就是高大上啊!啥都是配置文件就能夠了。所以第一步就是弄清楚配置文件使用和總體框架的流程! Spring web mvc最重要的當

web過濾器

調用 進行 比較 人員 資源 std write des jsp Filter也稱之為過濾器,它是Servlet技術中比較激動人心的技術,WEB開發人員通過Filter技術,對web服務器管理的所有web資源:例如Jsp, Servlet, 靜態圖片文件或靜態 html 文