SpringMVC框架中的過濾器設置

SpringMVC框架是一個成熟的優秀java web開發框架,學習研究框架設計有助於我們更好的理解和掌握spring MVC,設計和寫出更符合的結構和代碼。

本節主要是研讀SpringMVC框架中的過濾器設置,以編碼處理過濾器爲例來學習框架內是怎樣設置過濾器的。


如上所示的spring-web.jar包結構所示, 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。

過濾器放在容器結構的什麼位置?

過濾器放在web資源之前,可以在請求抵達它所應用的web資源(可以是一個Servlet、一個Jsp頁面,甚至是一個HTML頁面)之前截獲進入的請求,並且在它返回到客戶之前截獲輸出請求。Filter:用來攔截請求,處於客戶端與被請求資源之間,目的是重用代碼。Filter鏈,在web.xml中哪個先配置,哪個就先調用。在filter中也可以配置一些初始化參數。

Java中的Filter 並不是一個標準的Servlet ,它不能處理用戶請求,也不能對客戶端生成響應。 主要用於對HttpServletRequest 進行預處理,也可以對HttpServletResponse 進行後處理,是個典型的處理鏈。

Filter 有如下幾個種類:

l  用戶授權的Filter: Filter 負責檢查用戶請求,根據請求過濾用戶非法請求。

l  日誌Filter: 詳細記錄某些特殊的用戶請求。

l  負責解碼的Filter: 包括對非標準編碼的請求解碼。

l  能改變XML 內容的XSLTFilter 等。

Filter 有如下幾個用處 :

l  在HttpServletRequest 到達Servlet 之前,攔截客戶的HttpServletRequest 。

l  根據需要檢查HttpServletRequest ,也可以修改HttpServletRequest 頭和數據。

l  在HttpServletResponse 到達客戶端之前,攔截HttpServletResponse 。

l  根據需要檢查HttpServletResponse ,可以修改HttpServletResponse 頭和數據。

創建一個 Filter 只需兩個步驟

(1)創建Filter 處理類: 

(2)在web.xml 文件中配置Filter 。

創建Filter 必須實現javax.servlet.Filter 接口,在該接口中定義了三個方法。

• void init(FilterConfig config): 用於完成Filter 的初始化。 

• void destroy(): 用於Filter 銷燬前,完成某些資源的回收。 

• void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 實現過濾功能,該方法就是對每個請求及響應增加的額外處理。 

過濾器Filter也具有生命週期:init()->doFilter()->destroy(),由部署文件中的filter元素驅動。

參照編碼過濾器示例來查看怎麼實現的

  1. 首先配置在web.xml文件裏的規則如下
<!-- 編碼處理過濾器 -->
   <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
     <param-name>encoding</param-name>
     <param-value>utf-8</param-value>
  </init-param>
  <init-param>
     <param-name>forceEncoding</param-name>
     <param-value>true</param-value>
  </init-param>
    </filter>
    <filter-mapping>
   <filter-name>encodingFilter</filter-name>
   <url-pattern>*.do</url-pattern>
    </filter-mapping>

其中,filter-class 爲過濾器Filter類,init-prama爲注入的set參數

Filter-mapping中的url-pattern爲過濾的url類型

類的繼承關係

CharacterEncodingFilterr類繼承了 OncePerRequestFilter 類

public class CharacterEncodingFilter extends OncePerRequestFilter

而 OncePerRequestFilter 類又繼承了 GenericFilterBean 類

public abstract class OncePerRequestFilter extends GenericFilterBean

public abstract class GenericFilterBean implements

Filter, BeanNameAware, EnvironmentAware, ServletContextAware, InitializingBean, DisposableBean

設置編碼的核心代碼爲

@Override
   protected void doFilterInternal(
  HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  throws ServletException, IOException {
      if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
  request.setCharacterEncoding(this.encoding);
  if (this.forceEncoding) {
     response.setCharacterEncoding(this.encoding);
  }
      }
      filterChain.doFilter(request, response);
   }
 

其中filterChain爲過濾器鏈,表示執行完這個過濾器之後接着執行下一個過濾器

區別

我們在使用過濾器時,通常沒必要知道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的某部分功能,當然,具體如何執行由它們的子類規定,若你需要實現自己的過濾器,也可以根據上文所述繼承你所需要的類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章