天天看點

JAVA中的過濾器與監聽器

JAVA中的過濾器與監聽器

過濾器

什麼是過濾器

過濾器就是 Servlet 的進階特性之一,就是一個具有攔截/過濾功能的一個東西,在生活中過濾器可以是香煙濾嘴,濾紙,淨水器,空氣淨化器等,在 Web 中僅僅是一個實作了 Filter 接口的 Java 類而已。

特點:雙向,攔截請求,攔截響應

作用:

過濾器可以對所有的請求或者響應做攔截操作

Web 中過濾器的作用:

1.可以在請求資源之前設定請求的編碼

2.可以進行登入校驗

3.可以進行請求參數的内容的過濾

4.資料壓縮 / 資料加密 / 資料格式的轉換

5.可以設定浏覽器相關的資料

JAVA中的過濾器與監聽器

1、Filter工作原理(執行流程)

當用戶端發出Web資源的請求時,Web伺服器根據應用程式配置檔案設定的過濾規則進行檢查,若客戶請求滿足過濾規則,則對客戶請求/響應進行攔截,對請求頭和請求資料進行檢查或改動,并依次通過過濾器鍊,最後把請求/響應交給請求的Web資源處理。請求資訊在過濾器鍊中可以被修改,也可以根據條件讓請求不發往資源處理器,并直接向客戶機發回一個響應。當資源處理器完成了對資源的處理後,響應資訊将逐級逆向傳回。同樣在這個過程中,使用者可以修改響應資訊,進而完成一定的任務。

伺服器會按照web.xml中過濾器定義的先後循序組裝成一條鍊,然後一次執行其中的doFilter()方法。執行的順序應該就是執行第一個過濾器的chain.doFilter()之前的代碼,第二個過濾器的chain.doFilter()之前的代碼,請求的資源,第二個過濾器的chain.doFilter()之後的代碼,第一個過濾器的chain.doFilter()之後的代碼,最後傳回響應。

過濾器的執行流程:

執行第一個過濾器的chain.doFilter()之前的代碼——>第二個過濾器的chain.doFilter()之前的代碼——>……——>第n個過濾器的chain.doFilter()之前的代碼——>所請求servlet的service()方法中的代碼——>所請求servlet的doGet()或doPost()方法中的代碼——>第n個過濾器的chain.doFilter()之後的代碼——>……——>第二個過濾器的chain.doFilter()之後的代碼——>第一個過濾器的chain.doFilter()之後的代碼。

過濾器生命周期的四個階段:

1、執行個體化:Web容器在部署Web應用程式時對所有過濾器進行執行個體化。Web容器回調它的無參構造方法。2、初始化:執行個體化完成之後,馬上進行初始化工作。Web容器回調init()方法。

3、過濾:請求路徑比對過濾器的URL映射時。Web容器回調doFilter()方法——主要的工作方法。

4、銷毀: Web容器在解除安裝Web應用程式前,Web容器回調destroy()方法。

Servlet過濾器開發步驟:

1、建立實作javax.servlet.Filter接口的類。

2、過濾器的xml配置。

Servlet過濾器API

Servlet過濾器API包含了3個接口,它們都在javax.servlet包中,分别是Filter接口FilterChain接口和FilterConfig接口。

public Interface Filter所有的過濾器都必須實作Filter接口。該接口定義了init,doFilter0,destory()三個方法:

(1) public void init (FilterConfig filterConfig)

當開始使用servlet過濾器服務時,Web容器調用此方法一次,為服務準備過濾器;然後在需要使用過濾器的時候調用doFilter(),傳送給此方法的FilterConfig對象,包含servlet過濾器的初始化參數。

(2)public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)

每個過濾器都接受目前的請求和響應,且FilterChain過濾器鍊中的過濾器(應該都是符合條件的)都會被執行。doFilter方 法中,過濾器可以對請求和響應做它想做的一切,通過調用他們的方法收集資料,或者給對象添加新的行為。過濾器通過傳送至 此方法的FilterChain參數,調用chain.doFilterO将控制權傳送給下一個過濾器。當這個調用傳回後,過濾器可以在它的 Filter方法的最後對響應做些其他的工作。如果過濾器想要終止請求的處理或得到對響應的完全控制,則可以不調用下一個過濾 器,而将其重定向至其它一些頁面。當鍊中的最後一個過濾器調用chain.doFilterO方法時,将運作最初請求的Servlet。

(3)public void destroy()

一旦doFilterO方法裡的所有線程退出或已逾時,容器調用

此方法。伺服器調用destoryO以指出過濾器已結束服務,用于釋

放過濾器占用的資源。

public interface FilterChain

public void doFilter(ServletRequest request,ServletResponse response)

此方法是由Servlet容器提供給開發者的,用于對資源請求過濾鍊的依次調用,通過FilterChain調用過濾鍊中的下一個過濾 器,如果是最後一個過濾器,則下一個就調用目标資源。

public interface FilterConfig

FilterConfig接口檢索過濾器名、初始化參數以及活動的Servlet上下文。該接口提供了以下4個方法:

(1)public java.1ang.String getFilterName0

傳回web.xml部署檔案中定義的該過濾器的名稱。

(2)public ServletContext getServletContextO

傳回調用者所處的servlet上下文。

(3)public java.1ang.String getlnitParameter(java.1ang.String name)

傳回過濾器初始化參數值的字元串形式,當參數不存在時,傳回nul1.name是初始化參數名。

(4)public java.util.Enumeration getlnitParameterNames()

以Enumeration形式傳回過濾器所有初始化參數值,如果沒有初始化參數,傳回為空。

監聽器

什麼是監聽器:

監聽器用于監聽web應用中某些對象、資訊的建立、銷毀、增加,修改,删除等動作的發生,然後作出相應的響應處理。當範圍對象的狀态發生變化的時候,伺服器自動調用監聽器對象中的方法。常用于統計線上人數和線上使用者,系統加載時進行資訊初始化,統計網站的通路量等等。

作用:

1.監聽 web 應用的建立和銷毀(除了對web應用的監聽外,還能監聽session和request的生命周期,以及他們的attribute發生的變化)

2.attribute發生的變化。

示例:用監聽器統計網站線上人數

@WebListener
public class OnlineListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        System.out.println("OnlineListener.attributeAdded");

        String name =  se.getName();
        //登入使用者的session發生變化
        if("account".equals(name)){
            ServletContext application = se.getSession().getServletContext();
            int online_num = application.getAttribute("online_num") == null ? 0 : (Integer) application.getAttribute("online_num");
            System.out.println("online_num = " + online_num);
            online_num++;
            application.setAttribute("online_num",online_num);
        }
      
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("OnlineListener.attributeRemoved");

        String name =  se.getName();
        //退出 使用者的session發生變化
        if("account".equals(name)){
            ServletContext application = se.getSession().getServletContext();
            int online_num = application.getAttribute("online_num") == null ? 0 : (Integer) application.getAttribute("online_num");
            System.out.println("online_num = " + online_num);
            online_num--;
            application.setAttribute("online_num",online_num);
        }

    }
}
           

繼續閱讀