Spring:Spring-過濾器Filter原理

1.美圖

在這裏插入圖片描述

2.概述

2.1 Filter基本工作原理

  1. Filter 程序是一個實現了特殊接口的 Java 類,與 Servlet 類似,也是由 Servlet 容器進行調用和執行的。
  2. 當在 web.xml 註冊了一個 Filter 來對某個 Servlet 程序進行攔截處理時,它可以決定是否將請求繼續傳遞給 Servlet 程序,以及對請求和響應消息是否進行修改。
  3. 當 Servlet 容器開始調用某個 Servlet 程序時,如果發現已經註冊了一個 Filter 程序來對該 Servlet 進行攔截,那麼容器不再直接調用 Servlet 的 service 方法,而是調用 Filter 的 doFilter 方法,再由 doFilter 方法決定是否去激活 service 方法。
  4. 但在 Filter.doFilter 方法中不能直接調用 Servlet 的 service 方法,而是調用 FilterChain.doFilter 方法來激活目標 Servlet 的 service 方法,FilterChain 對象時通過 Filter.doFilter 方法的參數傳遞進來的。
  5. 只要在 Filter.doFilter 方法中調用 FilterChain.doFilter 方法的語句前後增加某些程序代碼,這樣就可以在 Servlet 進行響應前後實現某些特殊功能。
  6. 如果在 Filter.doFilter 方法中沒有調用 FilterChain.doFilter 方法,則目標 Servlet 的 service 方法不會被執行,這樣通過 Filter 就可以阻止某些非法的訪問請求。

2.2 Filter鏈

  1. 在一個 Web 應用程序中可以註冊多個 Filter 程序,每個 Filter 程序都可以對一個或一組 Servlet 程序進行攔截。如果有多個 Filter 程序都可以對某個 Servlet 程序的訪問過程進行攔截,當針對該 Servlet 的訪問請求到達時,Web 容器將把這多個 Filter 程序組合成一個 Filter 鏈(也叫過濾器鏈)。
  2. Filter 鏈中的各個 Filter 的攔截順序與它們在 web.xml 文件中的映射順序一致,上一個 Filter.doFilter 方法中調用 FilterChain.doFilter 方法將激活下一個 Filter的doFilter 方法,最後一個 Filter.doFilter 方法中調用的 FilterChain.doFilter 方法將激活目標 Servlet的service 方法。
  3. 只要 Filter 鏈中任意一個 Filter 沒有調用 FilterChain.doFilter 方法,則目標 Servlet 的 service 方法都不會被執行。

2.3 Filter接口

一個 Filter 程序就是一個 Java 類,這個類必須實現 Filter 接口。javax.servlet.Filter 接口中定義了三個方法:init、doFilter、destory

package javax.servlet;

import java.io.IOException;

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}

2.3.1 init 方法

  1. 在 Web 應用程序啓動時,Web 服務器(Web 容器)將根據其 web.xml 文件的配置信息來創建每個註冊的 Filter 的實例對象,並將其保存在內存中。
  2. Web 容器創建 Filter 的實例對象後,將立即調用該 Filter 對象的 init 方法。init 方法在 Filter 生命週期中僅被執行一次,Web 容器在調用 init 方法時,會傳遞一個包含 Filter 的配置和運行環境信息的 FilterConfig 對象。
public voic init(FilterConfig filterConfig) throws ServletException

  1. 開發人員可以在 init 方法中完成與構造方法類似的初始化功能,要注意的是:如果初始化代碼要使用到 FilterConfig 對象,這些代碼只能在 init 方法中編寫,而不能在構造方法中編寫(尚未調用 init 方法,即並沒有創建 FilterConfig 對象,要使用它則必然出錯)。

2.3.2 doFilter 方法

當一個 Filter 對象能夠攔截訪問請求時,Servlet 容器將調用 Filter 對象的 doFilter 方法。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException.ServletException

其中,參數 requestresponseWeb 容器或 Filter 鏈中上一個 Filter 傳遞過來的請求和響應對象;參數 chain 爲代表當前 Filter 鏈的對象。

2.3.3 destroy 方法

該方法在 Web 容器卸載 Filter 對象之前被調用,也僅執行一次。可以完成與 init 方法相反的功能,釋放被該 Filter 對象打開的資源,例如:關閉數據庫連接和 IO 流。

3.FilterChain接口

該接口用於定義一個 Filter 鏈的對象應該對外提供的方法,這個接口只定義了一個 doFilter 方法。

public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException

FilterChain 接口的 doFilter 方法用於通知 Web 容器把請求交給 Filter 鏈中的下一個 Filter 去處理,如果當前調用此方法的 Filter 對象是Filter 鏈中的最後一個 Filter,那麼將把請求交給目標 Servlet 程序去處理。

4.FilterConfig 接口

  1. 與普通的 Servlet 程序一樣,Filter 程序也很可能需要訪問 Servlet 容器。Servlet 規範將代表 ServletContext 對象和 Filter 的配置參數信息都封裝到一個稱爲 FilterConfig 的對象中。
  2. FilterConfig 接口則用於定義 FilterConfig 對象應該對外提供的方法,以便在 Filter 程序中可以調用這些方法來獲取 ServletContext 對象,以及獲取在 web.xml 文件中爲 Filter 設置的友好名稱和初始化參數。
  3. FilterConfig接口定義的各個方法:
getFilterName 方法,返回 <filter-name> 元素的設置值。

getServletContext 方法,返回 FilterConfig 對象中所包裝的 ServletContext 對象的引用。

getInitParameter 方法,用於返回在 web.xml 文件中爲 Filter 所設置的某個名稱的初始化的參數值。

getInitParameterNames 方法,返回一個 Enumeration 集合對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章