1. 程式人生 > >Servlet學習總結(10)監聽器

Servlet學習總結(10)監聽器

監聽器概念

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

監聽物件:

  1. ServletContext:application,整個應用只存在一個
  2. HttpSession:session,針對每一個對話
  3. ServletRequest:request,針對每一個客戶請求

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

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

監聽器使用

建立步驟:

  • 建立一個實現監聽器介面的類
  • 配置web.xml檔案,註冊監聽器
<listener>
    <listener-class>com.test.className</listener-class>
</listener>

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

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

監聽器的分類

按照監聽的物件劃分

  • 用於監聽應用程式環境物件(ServletContext)的事件監聽器,實現ServletContextListener、ServletContextAttributeListener介面
  • 用於監聽使用者會話物件(HttpSeesion)的事件監聽器,實現HttpSessionListener、HttpSessionAttributeListener介面
  • 用於監聽請求訊息物件(ServletRequest)的事件監聽器,實現ServletRequestListener、ServletRequestAttributeListener介面

按照監聽事件劃分

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

根據監聽物件不同分別實現ServletContextListener、HttpSessionListener、ServletRequestListener介面。 

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

        //監聽應用程式環境物件(ServletContext)的事件監聽器
        ServletContext sc = this.getServletContext(); //建立context
        sc.setAttribute("Application","Application新增資料");   //新增Application
        sc.setAttribute("Application","Application更新資料");   //新增Application
        sc.removeAttribute("Application");                        //新增Application

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

生命週期:伺服器啟動>伺服器關閉

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

<context-param>
    <param-name>屬性名</param-name>
    <param-value>屬性值</param-value>
</context-param>
    /*
    * 監聽Application物件的建立的銷燬
    * */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //監聽Application的建立
        //獲取web.xml中配置的屬性
        //String value=servletContextEvent.getServletContext().getInitParameter("屬性名");
        System.out.println("MyListener.contextInitialized(Application建立成功)");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //監聽Application的銷燬
        System.out.println("MyListener.contextDestroyed(Application銷燬成功)");
    }


    /*
    * 監聽Application作用域資料的變更
    * */
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        //監聽Application作用域資料的新增
        System.out.println("MyListener.attributeAdded(Application新增一條資料)"+servletContextAttributeEvent.getName()
                +":"+servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        //監聽Application作用域資料的刪除
        System.out.println("MyListener.attributeRemoved(Application刪除一條資料)"+servletContextAttributeEvent.getName()
                +":"+servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        //監聽Application作用域資料的更新
        System.out.println("MyListener.attributeReplaced(Application更新一條資料)"+servletContextAttributeEvent.getName()
                +":"+servletContextAttributeEvent.getValue());
    }

2、HttpSession的建立和銷燬:sessionCreated和sessionDestroyed方法

        //監聽使用者會話物件(HttpSession)的事件監聽器
        HttpSession hs = req.getSession();                       //建立session
        hs.setAttribute("Session","Session新增資料");       //新增session
        hs.setAttribute("Session","Session更新資料");       //更新session
        hs.removeAttribute("Session");                        //更新session
        hs.invalidate();                                        //銷燬session

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

生命週期:建立session>銷燬session

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

<session-config>
    <session-timeout>10</session-timeout>
</session-config>
    /*
    * 監聽Session物件的建立的銷燬
    * */
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        //監聽session的建立
        System.out.println("MyListener.sessionCreated(Session建立成功)");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        //監聽session的銷燬
        System.out.println("MyListener.sessionDestroyed(Session銷燬成功)");
    }


    /*
    * 監聽Session作用域資料的變更
    * */
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        //監聽Session作用域資料的新增
        System.out.println("MyListener.attributeAdded(Session增加一條資料)"+httpSessionBindingEvent.getName()
                +":"+httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        //監聽Session作用域資料的刪除
        System.out.println("MyListener.attributeRemoved(Session更新一條資料)"+httpSessionBindingEvent.getName()
                +":"+httpSessionBindingEvent.getValue());

    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        //監聽Session作用域資料的更新
        System.out.println("MyListener.attributeReplaced(Session刪除一條資料)"+httpSessionBindingEvent.getName()
                +":"+httpSessionBindingEvent.getValue());
    }

3、ServletRequest的建立和銷燬:requestInitialized和requestDestroyed方法

        //監聽請求訊息物件(ServletRequest)的事件監聽器
        req.setAttribute("Request","Request新增資料");      //新增request
        req.setAttribute("Request","Request更新資料");      //更新request
        req.removeAttribute("Request");                       //刪除request

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

生命週期:請求開始>請求結束

    /*
    * 監聽Request物件的建立和銷燬
    * */
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        //建立時呼叫
        System.out.println("MyListener.requestDestroyed(Request銷燬成功)");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        //銷燬時呼叫
        System.out.println("MyListener.requestInitialized(Request建立成功)");
    }

    /*
    * 監聽Request作用域資料的變更
    * */
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        //監聽request作用域資料的新增
        System.out.println("MyListener.attributeAdded(Request增加一條資料)"+servletRequestAttributeEvent.getName()
                +":"+servletRequestAttributeEvent.getValue());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        //監聽request作用域資料的刪除
        System.out.println("MyListener.attributeRemoved(Request刪除一條資料)"+servletRequestAttributeEvent.getName()
                +":"+servletRequestAttributeEvent.getValue());
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        //監聽request作用域資料的變更
        System.out.println("MyListener.attributeReplaced(Request變更一條資料)"+servletRequestAttributeEvent.getName()
                +":"+servletRequestAttributeEvent.getValue());
    }

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

根據監聽物件不同分別實現ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener介面。

實現方法:attributeAdded、attributeRemoved、attributeReplaced

獲取監聽資料的鍵:servletRequestAttributeEvent.getName()

獲取監聽資料的值:servletRequestAttributeEvent.getValue()

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

HttpSession中的物件狀態:

    繫結→解除繫結;鈍化→活化

實現介面及方法:

    HttpSessionBindingListener介面(valueBound和valueUnbound方法)、HttpSessionActivationListener介面(sessionWillPassivate和sessionDidActivate方法)

注意:

  • 要實現鈍化和活化必須實現Serializable介面
  • 不需要在web.xml中註冊
  • 繫結:通過setAttribute儲存到session物件當中
  • 解除繫結:通過removeAttribue去除
  • 鈍化:將session物件持久化到儲存裝置上
  • 活化:將session物件從儲存裝置上進行恢復

session鈍化機制:

  1. 把伺服器不常使用的session物件暫時序列化到系統檔案或者是資料庫中,當使用時反序列化到記憶體中,整個過程由伺服器自動完成;
  2. session的鈍化機制由SessionManager管理,建立一個普通的JavaBean繫結和接觸需要實現HttpSessionBindingListener介面

網站登入計數

public class Listener implements HttpSessionListener,ServletContextListener{

    /**
     * session被銷燬時人數自增
     * @param httpSessionEvent
     */
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        //獲取ServletContext物件
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        //獲取線上統計人數的變數
        int count = (int) sc.getAttribute("count");
        sc.setAttribute("count",++count);

    }

    /**
     * session被銷燬時人數自減
     * @param httpSessionEvent
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        int count = (int) sc.getAttribute("count");
        sc.setAttribute("count",--count);
    }

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //獲取Application
        ServletContext sc = servletContextEvent.getServletContext();
        //在Application物件儲存變數用來統計線上人數
        sc.setAttribute("count",0);

    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}