1. 程式人生 > >物件作用域與Servlet事件監聽器

物件作用域與Servlet事件監聽器

物件作用域

1、  物件屬性所在作用域:誰能看到並使用這個屬性,以及它能存活多久。

2、  應用上下文ServletContext物件作用域:

  • 對於整個Web應用,只有一個ServletContext物件,而且在Web應用中的所有地方都可以訪問它;
  • ServletContext物件由Web容器建立並例項化,它可以多執行緒同時讀/寫屬性;
  • 是執行緒不安全的,所以需要對屬性的讀/寫進行同步處理或進行深度複製;
  • 當web容器關閉,會銷燬ServletContext物件;
  • 建議:在ServletContext物件中儘可能少量儲存不會被修改的資料,常用的方法是用單例模式來處理共享資料。

3、  HTTPSession物件作用域:

  • 用於維護伺服器與一個客戶的會話狀態。在HttpSession物件中設定屬性,不能被Web應用中的所有地方訪問;
  • HttpSession物件在使用者會話期間存在,只能在處理屬於同一個HttpSession的請求的執行緒中被訪問;
  • HttpSession物件的屬性訪問理論上是執行緒安全的,但當用戶開啟多個屬於一個程序的瀏覽器視窗,在這些視窗的訪問屬於同一個HttpSession物件,會出現多次請求,需要多個工作執行緒處理請求,可能造成執行緒不安全,這時需要對屬性的讀寫進行執行緒同步處理,一般使用同步塊synchronized來處理;
  • 當會話被銷燬,HttpSession的設定屬性也會被銷燬;

4、  HTTPServletRequest物件作用域:

  • HttpServletRequest物件用於一次客戶端請求過程。對於每一個請求,由一個執行緒來執行,都會建立一個新的HttpServletRequest物件;
  • 所以HttpServletRequest物件只能在一個執行緒中被訪問,它是執行緒安全的;

5、  三個物件的共同點:都是內建物件,都相當於容器,可以存取屬性,擁有相同的屬性操作方法。

6、  三個物件的不同點:

  • 作用域大小比較:ServletContext>HttpSession物件>HttpServletRequest物件;
  • 存活時間長短比較:ServletContext>HttpSession物件>HttpServletRequest物件;
  • 資源消耗多少比較:ServletContext>HttpSession物件>HttpServletRequest物件;
  • 執行緒安全性比較:ServletContext<HttpSession物件<HttpServletRequest物件;

Servlet事件監聽事件

一、Servlet監聽器的概念

Servlet監聽器是Servlet規範中定義的一種特殊類,用於監聽ServletContext、HttpSession和ServletRequest等域物件的建立與銷燬事件,以及監聽這些域物件中屬性發生修改的事件。

監聽物件

1、ServletContext:application,整個應用只存在一個

2、HttpSession:session,針對每一個對話

3、ServletRequest:request,針對每一個客戶請求

監聽內容:建立、銷燬、屬性改變事件

監聽作用:可以在事件發生前、發生後進行一些處理,一般可以用來統計線上人數和線上使用者、統計網站訪問量、系統啟動時初始化資訊等。

二、監聽器的基本使用

建立步驟

1、建立一個實現監聽器介面的類

2、配置web.xml檔案,註冊監聽器

<listener>
    <listener-class>完整類名</listener-class>
</listener>

監聽器的啟動順序:按照web.xml的配置順序來啟動

載入順序:監聽器>過濾器>Servlet

三、監聽器的分類

3.1 按照監聽的物件劃分

1、用於監聽應用程式環境物件(ServletContext)的事件監聽器,實現ServletContextListener、ServletContextAttributeListener介面

2、用於監聽使用者會話物件(HttpSeesion)的事件監聽器,實現HttpSessionListener、HttpSessionAttributeListener介面

3、用於監聽請求訊息物件(ServletRequest)的事件監聽器,實現ServletRequestListener、ServletRequestAttributeListener介面

3.2按照監聽事件劃分

1、監聽域物件自身的建立和銷燬的事件監聽器

根據監聽物件不同分別實現ServletContextListenerHttpSessionListenerServletRequestListener介面。 

①ServletContext的建立和銷燬:contextInitialized方法和contextDestroyed方法

public void contextInitialized(ServletContextEvent sce)//ServletContext建立時呼叫
public void contextDestroyed(ServletContextEvent sce)//ServletContext銷燬時呼叫

主要用途:作為定時器、載入全域性屬性物件、建立全域性資料庫連線、載入快取資訊等

例項:

在web.xml中可以配置專案初始化資訊,在contextInitialized方法中進行啟動

<context-param>
    <param-name>屬性名</param-name>
    <param-value>屬性值</param-value>
</context-param>

自定義監聽器

複製程式碼
public class MyFirstListener implements ServletContextListener{
    public void contextInitialized(ServletContextEvent sce){
        //獲取web.xml中配置的屬性
        String value=sce.getServletContext().getInitParameter("屬性名");
        System.out.println(value);
  }
    public void contextDestroyed(ServletContextEvent sce){
        //關閉時操作
  }
}
複製程式碼

 ②HttpSession的建立和銷燬:sessionCreatedsessionDestroyed方法

public void sessionCreated(HttpSessionEvent se)//session建立時呼叫
public void sessionDestroyed(HttpSessionEvent se)//session銷燬時呼叫

主要用途:統計線上人數、記錄訪問日誌等

【注】

 web.xml配置session超時引數,單位:分,session超時的時間並不是精確的

<session-config>
    <session-timeout>10</session-timeout>
</session-config>

 ③ServletRequest的建立和銷燬:requestInitializedrequestDestroyed方法

public void requestInitialized(ServletRequestEvent sre)//request建立時呼叫
public void requestDestroyed(ServletRequestEvent sre)//request銷燬時呼叫

主要用途:讀取request引數,記錄訪問歷史

例項: 

複製程式碼
public class MySRequestListener implements SevletRequestListener{
    public void requestInitialized(ServletRequestEvent sre){
        String value=sre.getServletRequest().getParameter("key");//獲取request中的引數
        System.out.println(value);
    }
    public void requestDestroyed(ServletRequestEvent sre){  
        System.out.println("request destroyed");
    }
}   
複製程式碼

2、監聽域物件中的屬性的增加和刪除的事件監聽器

  根據監聽物件不同分別實現ServletContextAttributeListenerHttpSessionAttributeListenerServletRequestAttributeListener介面。

  實現方法:attributeAddedattributeRemovedattributeReplaced

3、監聽繫結到HttpSeesion域中的某個物件的狀態的事件監聽器(建立普通JavaBean)

  HttpSession中的物件狀態:繫結→解除繫結;鈍化→活化

  實現介面及方法:HttpSessionBindingListener介面(valueBoundvalueUnbound方法)、HttpSessionActivationListener介面(sessionWillPassivatesessionDidActivate方法)

【注1】①要實現鈍化和活化必須實現Serializable介面

           ②不需要在web.xml中註冊

【注2】

  繫結:    通過setAttribute儲存到session物件當中

  解除繫結:  通過removeAttribue去除

  鈍化:    將session物件持久化到儲存裝置上

  活化:    將session物件從儲存裝置上進行恢復

  session鈍化機制:

    ①把伺服器不常使用的session物件暫時序列化到系統檔案或者是資料庫中,當使用時反序列化到記憶體中,整個過程由伺服器自動完成;

    ②session的鈍化機制由SessionManager管理,建立一個普通的JavaBean繫結和接觸需要實現HttpSessionBindingListener介面

四、Servlet3.0下監聽器的使用

4.1 使用條件

  1、使用servlet3.0新標準的jar包

  2、JDK在1.6以上版本

  3、編譯器的編譯級別為6.0

  4、在web.xml檔案中,使用3.0規範

  5、使用支援servlet3.0特性的web容器,比如tomcat7

4.2 servlet3.0下監聽器的用法

使用註解 @WebListener 即可,無法去定義監聽器的順序

@WebListener的常用屬性
屬性名 型別 是否可選 描述
value String 該監聽器的描述資訊
@WebListener("This is a listener")
public class FirstListener impliements ServletRequestListener{}

該註解用於將類宣告為監聽器,被 @WebListener 標註的類必須實現以下至少一個介面:

  ServletContextListener

  ServletContextAttributeListener

  ServletRequestListener

  ServletRequestAttributeListener

  HttpSessionListener

  HttpSessionAttributeListener