天天看點

java過濾器定義_Java ---Filter過濾器這是index頁面

Filter可以視作是servlet的加強版,主要用作對使用者的請求進行預處理,或者對傳回給用戶端的結果進行再次加工,是一個典型的鍊式處理模式。本篇簡單介紹filter的基本使用方法,主要涉及以下内容:

Filter的背景知識

使用Filter的流程

Filter的生命周期

一個完整的執行個體

一、Filter的簡單介紹

Filter在英文中是過濾器的意思,當然在此處的使用也是完美的切合了它的意思,我們使用filter的主要目的就是完成一個過濾的作用。可以在一個請求到達servlet之前,将其截取進行邏輯判斷,然後決定是否放行到請求的servlet。也可以在一個response到達用戶端之前,截取結果進行邏輯判斷,然後決定是否允許傳回給用戶端。是以filter有如下幾個種類:

使用者授權的filter:filter負責判斷使用者是否有權限請求該頁面,給予過濾判斷

日志filter:截取某個使用者在本網站上的所有請求,記錄軌迹

負責解碼的filter:規定處理本次請求的解碼方式

最後需要注意的是,一個filter過濾器可以加在多個servlet控制器上,當然多個filter過濾器也是可以加在一個servlet控制器上的。由此也是可以看出來,我們使用filter往往是對一些公共的操作進行處理,例如:判斷使用者權限,解碼本次請求等,還比如,我們的web應用中某些頁面是需要使用者登入後才能通路的,以往我們都是在每個servlet頁面加上判斷控制,導緻代碼備援,有了filter,我們可以定義一個實作了filter的過濾器,讓需要判斷是否登入的頁面都加上這麼一個過濾器,可以大大降低代碼的備援程度。

二、Filter的使用流程

在Java中如果想要自定義一個filter過濾器的話,需要繼承Javax.servlet.Filter接口,這個接口中隻有三個方法:

default void init(FilterConfig filterConfig)

void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3)

default void destroy()

其中init和destroy方法是有預設實作的,也就是我們不是必須重寫這兩個方法,但是doFilter 這個方法是一個核心的方法,是我們必須要實作的。首先我們看init方法的作用,這個方法是用來初始化filter執行個體的,也就是當使用者請求了某個攔截器而此攔截器又比對了某個過濾器,此時web容器就會定位到該過濾器然後建立該filter類的執行個體對象并調用此執行個體的init方法,完成初始化工作。對于destroy方法毋庸置疑就是在過濾器執行結束的時候調用,主要完成對一些資源的釋放。下面主要看dofilter這個方法。

doFilter方法是filter接口中的核心方法,一旦建立完該過濾器的執行個體之後,會執行dofilter方法,所有的過濾邏輯都是在此方法中進行的。主要有三個參數,第一個參數是一個ServletRequest對象,HttpServletRequest繼承于此接口,當使用者請求某個攔截器的時候,檢測到此請求存在過濾器,于是會封裝好本次請求的相關資料,傳遞給dofilter的ServletRequest參數,ServletResponse參數的來源和ServletRequest是一樣的,都是由用戶端封裝過來的。至于第三個參數,這是一個FilterChain處理鍊,詳細的介紹等說明了web.xml中配置filter之後。

第一步如上,建立一個繼承自filter接口的類,并實作其中的三個方法。第二步是在web.xml中配置該類用于過濾哪些攔截器。web.xml代碼如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

version="3.1">

isLogin

Test_f.MyFilter

isLogin

/a

isLogin

/b

如上述的代碼,我們需要兩個操作,首先是定義一個filter,指定了該filter的name和相對應的過濾器類。然後我們可以通過filter-mapping映射過濾器和URL,此處使用了兩個映射,對該過濾器指定了對路徑名為/a和/b的請求進行攔截。當然這個url-pattern元素的值可以有以下三種形式,完全比對(/a/b等),目錄比對(/* 、 /abc/等),擴充名(.a,*.b等)。

了解了配置filter的主要操作之後,我們回去看過濾器類,我們說init方法是在首次建立filter執行個體的時候,用于執行初始化操作的,其中有個參數FilterConfig ,這是目前filter的配置資訊,其中方法如下:

String getFilterName();

ServletContext getServletContext();

String getInitParameter(String var1);

Enumeration getInitParameterNames();

其實在建立filter執行個體的時候,web容器會将此執行個體對應在web.xml中的配置資訊讀取并封裝成一個FilterConfig 對象傳遞給init方法,getFilterName方法就是我們在web.xml中配置的filter-name,getServletContext會擷取目前servlet的上下文,當我們在定義filter的時候使用來定義一些初始化參數的時候,就可以使用此方法來擷取這些初始化參數。getInitParameterNames方法用于擷取所有初始化參數的枚舉集合。這樣我們在init方法中就可以擷取這些配置參數,初始化filter執行個體。

上面我們隻定義了一個filter,如果我們對于一次請求需要執行多個filter,進行過濾操作的話,web容器會在你請求某個URL的時候,在web.xml中找到所有比對的filter,按照注冊的順序以FilterChain 鍊的形式傳遞到方法doFilter的第三個參數中,而這個filterChain中隻有一個方法:

void doFilter(ServletRequest var1, ServletResponse var2)

如果我們在 void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) 方法中調用var3.doFilter(var1,var2),就代表此filter執行個體結束,則web伺服器會檢查FilterChain對象中是否還有filter對象(因為這是一個鍊,filter的數量是大于等于一的),如果沒有就會放行,直接調用目标位址,如果還有filter對象,就會轉而執行下一個filter。正是由于這樣的機制,我們才可以對于一個URL請求添加多個filter過濾器。

三、一個簡單的執行個體

下面通過一個簡單的執行個體直覺的感受下filter過濾器的作用:

public class MyFilter implements Filter {

@Override

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

HttpServletRequest req = (HttpServletRequest)var1;

HttpSession session = req.getSession();

String state = (String)session.getAttribute("state");

if(state.equals("1")){

var3.doFilter(var1,var2);

}else{

HttpServletResponse response = (HttpServletResponse)var2;

response.sendRedirect("Error_page.html");

}

}

}

//web.xml

isLogin

Test_f.MyFilter

isLogin

/index.jsp

這是index頁面

//set.jsp

//為了使程式簡單,我們采用手動設定session

//在實際的項目中,當使用者登入之後自動設定session

我們首先通路set.jsp頁面設定本次會話的session值,然後修改浏覽器位址欄通路index.jsp頁面

java過濾器定義_Java ---Filter過濾器這是index頁面

敲下Enter鍵,結果如下:

java過濾器定義_Java ---Filter過濾器這是index頁面

我們先看,敲下Enter鍵之後,程式怎麼執行的,因為我們在web.xml中配置了MyFilter的攔截URL為index.jsp,是以當我們通路index.jsp的時候,會建立MyFilter 執行個體對象,封裝配置資訊到FilterConfig對象中,然後封裝request請求和response,還有從web.xml 中讀取的FilterChain對象傳入MyFilter的doFilter方法中,我們在其中擷取本次會話的session對象,取得其中的資料,如果為一放行,否則跳轉到錯誤頁面。此處的state的session值為0,我們在set.jsp中設定的,大家也可以在set.jsp頁面設定其值為1,這樣最終的結果會是這樣的:

java過濾器定義_Java ---Filter過濾器這是index頁面

上述的demo隻是為了簡單的示範,其實使用filter可以完成大大的降低我們的代碼的備援程度。這個例子是為了示範,是以很簡單。

四、Filter 的生命周期

當使用者請求某個頁面時候,會到web.xml中比對是否存在能夠比對上此次請求的filter,如果有封裝它的配置資訊,FilterChain鍊。然後調用init方法,完成初始化,接着調用dofilter方法,處理核心邏輯,當此執行個體被銷毀的時候,會調用destroy方法。

本篇文章結束,如果有了解錯誤,望大家指出!