1. 程式人生 > >Web基礎瞭解版10-Filter-Listener

Web基礎瞭解版10-Filter-Listener

Filter

對於WEB應用來說,過濾器是一個駐留在伺服器中的WEB元件,他可以擷取客戶端和WEB資源之間的請求和響應資訊。

在一個WEB應用中可以部署多個過濾器,多個過濾器就組成了一個過濾器鏈,請求和響應必須在經過多個過濾器後才能到達目標

當配置多個Filter以後就有一個執行順序的問題,實際執行順序是按照在web.xml檔案中servlet-mapping的順序決定的,如果順序越靠前越先被呼叫。

Filter介面

  • Filter是一個介面。

  • Filter是Java Web三大元件之一。(JavaWeb三大元件分別是:Servlet小程式、Filter過濾器、Listener監聽器)

  • 作用:1.檢查使用者訪問許可權

                2.設定請求響應編碼,解決亂碼問題

主要API

Filter

  • init(FilterConfig)方法用於初始化Filter

  • doFilter(ServletRequest,ServletResponse,FilterChain)作用和service()方法類似,是過濾請求和響應的主要方法。

  • destroy()用於在Filter物件被銷燬前做一些收尾工作。如:釋放資源等。

FilterConfig

FilterConfig物件在伺服器呼叫init()方法時傳遞進來。

  • getFilterName() 獲取Filter的名字

  • getServletContext() 獲取ServletContext物件(即application)

  • getInitParameter(String) 獲取Filter的初始化引數

  • getInitParameterNames() 獲取所有初始化引數的名字

FilterChain

FilterChain物件是在doFilter()方法被呼叫時作為引數傳遞進來的。

  • doFilter(ServletRequest,ServletResponse)方法用於呼叫Filter鏈上的下一個過濾器,如果當前過濾器為最後一個過濾器則將請求傳送到目標資源。

web.xml檔案中的Filter配置

<filter-mapping>
    <!-- Filter的名字 -->
    <filter-name>Filter1</filter-name>
    <!-- Filter1的過濾地址,表示過濾http://127.0.0.1:8080/day17/admin/user.jsp-->
    <url-pattern>/admin/user.jsp</url-pattern>
</filter-mapping>

 

除此之外在filter-mapping還有一個子標籤dispatcher,該標籤用來指定需要Filter處理的請求型別

<!-- 使用者直接訪問資源時,會呼叫Filter -->
<dispatcher>REQUEST</dispatcher>

<!-- 通過轉發訪問時,會呼叫Filter -->
<dispatcher>FORWARD</dispatcher>

<!-- 通過動態包含獲取時,會呼叫Filter -->
<dispatcher>INCLUDE</dispatcher>

<!-- 當通過異常處理訪問頁面時,會呼叫Filter -->
<dispatcher>ERROR</dispatcher>

 

這四種情況可以設定一個,也可以同時設定多個,如果不設定那麼預設為REQUEST

Filter生命週期

  1. 先執行Filter的構造方法

  2. 然後執行Filter的init()方法,物件建立後,馬上就被呼叫,對Filter做一些初始化操作

  3. 執行Filter的doFilter()方法,每次訪問目標資源,只要匹配過濾的地址,就會呼叫。

  4. 執行Filter的destroy()方法,伺服器停止時呼叫,用來釋放資源。

FilterConfig類

作用:

  • 獲取Filter在web.xml檔案中配置的名稱

  • 獲取Filter在web.xml檔案中配置的初始化引數

  • 通過FilterConfig類獲取ServletContext物件例項

    // 獲取Filter的名稱
    String filterName = filterConfig.getFilterName();// 獲取初始化引數。username的值
    String username = filterConfig.getInitParameter("username");// 獲取ServletContext的物件例項 
    ServletContext ctx = filterConfig.getServletContext();

     

FilterChain過濾器鏈

  • FilterChain是整個Filter過濾器的呼叫者。Filter與Filter之間的傳遞,或者Filter與請求資源之間的傳遞都靠FilterChain.doFilter方法。

  • 一般Filter.doFilter中的程式碼分為三段:

    • 第一段是FilterChain.doFilter之前的程式碼。一般用來做請求的攔截,檢查使用者訪問的許可權,訪問日記的記錄。引數編碼的設定等等操作。

    • 第二段是FilterChain.doFilter方法。此方法可以將程式碼的執行傳遞到下一個Filter中。或者是傳遞到使用者最終訪問的資源中。

    • 第三段是FilterChain.doFilter之後的程式碼。主要用過做一些日誌操作。我們很少會在第三段中做太多複雜的操作。

  • 在每一個Filter類的doFilter方法中,一定要呼叫chain.doFilter方法,除非你想要阻止使用者繼續往下面訪問。否則一定要呼叫FilterChain的doFilter方法。

Filter的攔截路徑

主要有以下兩種

  • 第一種:通過filter-mapping的url-pattern來配置(與Servlet的url-pattern的規則相同)

    • 精確匹配:/路徑/資源名

      比如:/index.html、/hello/index.jsp 、 /client/LoginServlet 等,只有在請求地址完全一樣時才會呼叫Filter

    • 目錄匹配:/路徑名/*

      比如1:/abc/* 表示可以攔截abc目錄下的所有資源,甚至是abc目錄下的其他目錄。

      比如2:/* 表示只要訪問專案根目錄下的資源就會呼叫Filter

    • 字尾名匹配:*.字尾名

      比如:*.jsp 表示攔截所有後綴為jsp檔案資源

  • 第二種:通過filter-mapping中的servlet-name來指定要過濾的Servlet

在Filter的filter-mapping中增加了一個servlet-name標籤,將該標籤的值設定成Servlet的名字,在訪問Servlet時就會呼叫該過濾器過濾請求。
  <filter-mapping>
    <filter-name>HelloFilter</filter-name>
    <servlet-name>HelloServlet</servlet-name>
  </filter-mapping>

 

Listener

Listener用於監聽JavaWeb程式中的事件,當事件被觸發時,監聽器中的指定方法將會被呼叫。

監聽物件的建立與銷燬

  • ServletContextListener

    • 作用:監聽ServletContext物件的建立與銷燬

    • 方法:

      public void contextInitialized ( ServletContextEvent sce ):ServletContext建立時呼叫

      public void contextDestroyed ( ServletContextEvent sce ):ServletContext銷燬時呼叫

    • ServletContextEvent物件

      • 作用:public ServletContext getServletContext ():獲取ServletContext物件

  • HttpSessionListener

    • 作用:監聽HttpSession物件的建立與銷燬

    • 方法:

      • public void sessionCreated ( HttpSessionEvent se ):HttpSession物件建立時呼叫

      • public void sessionDestroyed ( HttpSessionEvent se ):HttpSession物件銷燬時呼叫

    • HttpSessionEvent物件

      • 作用:public HttpSession getSession ():獲取當前HttpSession物件

  • ServletRequestListener

    • 作用:監聽ServletRequest物件的建立與銷燬

    • 方法:

      • public void requestInitialized ( ServletRequestEvent sre ):ServletRequest物件建立時呼叫

      • public void requestDestroyed ( ServletRequestEvent sre ):ServletRequest物件銷燬時呼叫

    • ServletRequestEvent物件

      • 作用:

        public ServletRequest getServletRequest ():獲取當前的ServletRequest物件。

        public ServletContext getServletContext ():獲取當前專案的ServletContext物件。

三種建立與銷燬的監聽器使用起來基本一致。

在web.xml檔案中註冊監聽器

<listener>
<listener-class>com.web.listener.MyServletContextListener</listener-class>
</listener>

 

監聽物件的屬性變化

  • ServletContextAttributeListener

    • 作用:監聽ServletContext中屬性的建立、修改和銷燬

    • 方法:

      public void attributeAdded(ServletContextAttributeEvent scab):向ServletContext中新增屬性時呼叫

      public void attributeRemoved(ServletContextAttributeEvent scab):從ServletContext中移除屬性時呼叫

      public void attributeReplaced(ServletContextAttributeEvent scab):當ServletContext中的屬性被修改時呼叫

    • ServletContextAttributeEvent物件

      • 作用:

        public String getName() :獲取修改或新增的屬性名

        public Object getValue():獲取被修改或新增的屬性值

        public ServletContext getServletContext ():獲取當前WEB應用的ServletContext物件

  • HttpSessionAttributeListener

    • 作用:監聽HttpSession中屬性的建立、修改和銷燬

    • 方法:

      public void attributeAdded ( HttpSessionBindingEvent se ):向HttpSession中新增屬性時呼叫

      public void attributeRemoved(HttpSessionBindingEvent se):從HttpSession中移除屬性時呼叫

      public void attributeReplaced(HttpSessionBindingEvent se):當HttpSession中的屬性被修改時呼叫

    • HttpSessionBindingEvent物件

      • 作用:

        public String getName() :獲取修改或新增的屬性名

        public Object getValue():獲取被修改或新增的屬性值

        public HttpSession getSession ():獲取當前的HttpSession物件

  • ServletRequestAttributeListener

    • 作用:監聽ServletRequest中屬性的建立、修改和銷燬

    • 方法:

      public void attributeAdded (ServletRequestAttributeEvent srae ):向ServletRequest中新增屬性時呼叫

      public void attributeRemoved(ServletRequestAttributeEvent srae):從ServletRequest中移除屬性時呼叫

      public void attributeReplaced(ServletRequestAttributeEvent srae):當ServletRequest中的屬性被修改時呼叫

    • ServletRequestAttributeEvent物件

      • 作用:

        public String getName():獲取修改或新增的屬性名

        public Object getValue():獲取被修改或新增的屬性值

        public ServletRequest getServletRequest () :獲取當前的ServletRequest物件

監聽Session內的物件

  • HttpSessionBindingListener

    • 作用:監聽某個物件在session域中的建立與移除。

    • 方法:

      public void valueBound(HttpSessionBindingEvent event):該類的例項被放到Session域中時呼叫

      public void valueUnbound(HttpSessionBindingEvent event):該類的例項從Session中移除時呼叫

    • HttpSessionBindingEvent物件

      • 作用:

        public HttpSession getSession ():獲取HttpSession物件

        public String getName():獲取操作的屬性名

        public Object getValue():獲取操作的屬性值

  • 使用:要監聽哪一個類,直接使該類實現HttpSessionBindingListener介面即可。

  • HttpSessionActivationListener

    • 作用:監聽某個物件在session中的序列化與反序列化。

    • 方法:

      public void sessionWillPassivate(HttpSessionEvent se):該類例項和Session一起鈍化到硬碟時呼叫

      public void sessionDidActivate(HttpSessionEvent se):該類例項和Session一起活化到記憶體時呼叫

    • HttpSessionEvent物件

      • 作用:

        public HttpSession getSession ():獲取HttpSession物件

  • 使用:要監聽哪一個類,直接使該類實現HttpSessionActivationListener介面即可。

注意:為被監聽類物件可以正常序列化到硬碟上,還需要讓該類實現java.io.Serializable介面

&n