day25-Listener監聽器

来源:https://www.cnblogs.com/liyuelian/archive/2022/11/27/16930560.html
-Advertisement-
Play Games

Listener監聽器 1.Listener監聽器介紹 Listener監聽器是JavaWeb三大組件之一。JavaWeb三大組件分別是:Servlet程式,Listener監聽器,Filter過濾器。 Listener是JavaEE的規範,即介面。 監聽器的作用是,監聽某種變化(一般就是對象的創建 ...


Listener監聽器

1.Listener監聽器介紹

  1. Listener監聽器是JavaWeb三大組件之一。JavaWeb三大組件分別是:Servlet程式,Listener監聽器,Filter過濾器。
  2. Listener是JavaEE的規範,即介面。
  3. 監聽器的作用是,監聽某種變化(一般就是對象的創建/銷毀,屬性變化),觸發對象方法完成相應的任務。
  4. JavaWeb中的監聽器共八個,目前最常用的是ServletContextListener,ServletContextAttributeListener,HttpSessionListener和ServletRequestListener

2.JavaWeb的監聽器

2.1ServletContextListener監聽器

  1. 作用:監聽ServletContext創建或者銷毀(當我們web應用啟動時,Tomcat就會創建ServletContext對象),即生命周期監聽
  2. 應用場景:
    • 載入初始化的配置文件;比如spring的配置文件
    • 任務調度(配合定時器Timer/TimerTask)
  3. 相關方法:
    • void contextInitialized(ServletContextEvent sce):創建ServletContext對象時觸發
    • void contextDestroyed(ServletContextEven sce):銷毀ServletContext對象時觸發

應用實例

  1. 首先創建一個項目,添加web支持,因為listener監聽器是Servlet規範,要使用就要引入Servlet.jar包

    image-20221127165358783
  2. 創建一個普通類,如果該類實現了某個監聽介面,那麼此類就是一個監聽器。該類可以監聽的事件由該類實現的監聽介面決定:

    package com.listener;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    /**
     * 1.當一個類實現了 ServletContextListener 介面時
     * 2.該類就是一個監聽器
     * 3.該類可以監聽的事件由該類實現的監聽介面決定 ,比如實現ServletContextListener介面,
     * 那麼該類就可以監聽ServletContext對象的創建和銷毀,以此類推
     * 4.下麵的MyServletContextListener就是一個監聽者
     * 5.當web應用啟動時,就會產生ServletContextEvent事件,會調用監聽器的對應事件處理方法
     * 如:contextInitialized(),同時會傳遞 事件對象
     * 6.程式員可以通過 ServletContextEvent 事件對象,來獲取需要的信息,然後再進行業務處理
     * 7.Tomcat怎麼知道這個監聽器存在呢? 因為我們需要在web.xml文件中進行配置,
     * 一旦配置後,tomcat啟動後就會反射實例化該監聽器,放到容器裡面去管理
     */
    public class MyServletContextListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            ServletContext servletContext = servletContextEvent.getServletContext();
            System.out.println("MyServletContextListener監聽到=" +
                    servletContext + "被創建...");
            //如果我們獲取到ServletContext對象..可以進行業務處理
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            ServletContext servletContext = servletContextEvent.getServletContext();
            System.out.println("MyServletContextListener監聽到=" +
                    servletContext + "被銷毀...");
            //比如可以對ServletContext 數據進行處理,或者日誌的管理...
            System.out.println("進行處理工作...");
        }
    }
    
  3. 配置web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             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_4_0.xsd"
             version="4.0">
        <!--配置監聽器-->
        <listener>
            <listener-class>com.listener.MyServletContextListener</listener-class>
        </listener>
    </web-app>
    
  4. 配置Tomcat

  5. 點擊啟動tomcat時,我們可以看到監聽器被觸發了:

    image-20221127172929861
  6. 點擊停止tomcat時,可以看到監聽器再一次被觸發:

    image-20221127172702514

2.2ServletContextAttributeListener監聽器

  1. 作用:監聽ServletContext屬性的變化
  2. 相關方法:
    • void attributeAdded(ServletContextAttributeEvent event):添加屬性時調用
    • void attributeReplaced(ServletContextAttributeEvent event):替換屬性時調用
    • void attributeRemoved(ServletContextAttributeEvent event):移除屬性時調用

應用實例

  1. 創建監聽器:MyServletContextAttributeListener
package com.listener;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;

public class MyServletContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("MyServletContextAttributeListener 監聽到添加屬性.." +
                servletContextAttributeEvent.getName() + "=" +
                servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("MyServletContextAttributeListener 監聽到刪除屬性.." +
                servletContextAttributeEvent.getName() + "=" +
                servletContextAttributeEvent.getValue());
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
        System.out.println("MyServletContextAttributeListener 監聽到修改屬性.." +
                servletContextAttributeEvent.getName() + "=" +
                servletContextAttributeEvent.getValue());
    }
}
  1. 創建servlet:HiServlet
package com.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class HiServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //給ServletContext對象操作屬性
        ServletContext servletContext = getServletContext();
        //添加屬性
        servletContext.setAttribute("name", "傑克");
        //修改屬性
        servletContext.setAttribute("name", "托馬斯");
        //刪除屬性
        servletContext.removeAttribute("name");

        System.out.println("HiServlet 處理完畢...");
    }
}
  1. web.xml:配置監聽器和servlet
<!--配置監聽器-->
<listener>
    <listener-class>com.listener.MyServletContextAttributeListener</listener-class>
</listener>
<!--配置HiServlet-->
<servlet>
    <servlet-name>HiServlet</servlet-name>
    <servlet-class>com.HiServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HiServlet</servlet-name>
    <url-pattern>/hiServlet</url-pattern>
</servlet-mapping>
  1. 重新發佈tomcat,在瀏覽器中訪問servlet,後臺輸出如下:

    image-20221127175211190

2.3HttpSessionListener監聽器

  1. 作用:監聽Session創建或銷毀,即生命周期監聽
  2. 相關方法:
    • void sessionCreated(HttpSessionEvent se):創建session時調用
    • void sessionDestroyed(HttpSessionEvent se):銷毀session時調用
  3. 使用方法和前面一樣,可以用於監聽用戶上線,離線

應用實例

  1. 創建監聽器:MyHttpSessionListener
package com.listener;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyHttpSessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        //當session被創建時,設置一個生命周期10s
        session.setMaxInactiveInterval(10);
        System.out.println("MyHttpSessionListener 監聽到session創建= " + session.getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        System.out.println("MyHttpSessionListener 監聽到session銷毀= " + session.getId());
    }
}
  1. 修改HiServlet代碼:
package com.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class HiServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取session對象
        request.getSession();
        System.out.println("HiServlet 處理完畢...");
    }
}
  1. 配置監聽器:
<listener>
    <listener-class>com.listener.MyHttpSessionListener</listener-class>
</listener>
  1. 現在我們重啟Tomcat,可以看到還沒有訪問HiServlet,就已經創建了兩個session。這是因為啟動Tomcat時,會預設訪問項目首頁面,tomcat會自動創建兩個session,這裡忽略即可。

    image-20221127181720060
  2. 在瀏覽器訪問HiServlet,可以看到後臺首先創建了一個session,在設置的生命周期內不訪問該session,顯示該session被銷毀。

    image-20221127182810302

HttpSessionListener監聽器可以用於監聽用戶上線離線

註意:這裡的session不是瀏覽器一關閉就銷毀,session的銷毀是伺服器端去輪詢決定的,因此如果想要用戶瀏覽器一關閉就銷毀session,可以通過前端在用戶瀏覽器關閉之前,向伺服器發送一個通知,伺服器收到通知後銷毀該session即可。

2.4HttpSessionAttributeListener監聽器

  1. 作用:監聽Session屬性的變化
  2. 相關方法:
    • void attributeAdded(ServletRequestAttributeEvent event):添加屬性時調用
    • void attributeReplaced(ServletRequestAttributeEvent event):替換屬性時調用
    • void attributeRemoved(ServletRequestAttributeEvent event):移除屬性時調用
  3. 使用少,使用方法和前面一樣。

應用實例

  1. 創建監聽器:MyHttpSessionAttributeListener
package com.listener;

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("MyHttpSessionAttributeListener 監聽到 session添加屬性= "
                + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("MyHttpSessionAttributeListener 監聽到 session刪除屬性= "
                + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        System.out.println("MyHttpSessionAttributeListener 監聽到 session修改屬性= "
                + httpSessionBindingEvent.getName() + "=" + httpSessionBindingEvent.getValue());
    }
}
  1. 修改HiServlet
package com.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class HiServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取session對象
        HttpSession session = request.getSession();
        //添加屬性
        session.setAttribute("age", 888);
        //修改屬性
        session.setAttribute("age", 999);
        //刪除屬性
        session.removeAttribute("age");
        System.out.println("HiServlet 處理完畢...");
    }
}
  1. 配置監聽器
<listener>
    <listener-class>com.listener.MyHttpSessionAttributeListener</listener-class>
</listener>
  1. redeployTomcat,在瀏覽器訪問hiServlet,後臺輸出如下:

    image-20221127185403369

2.5ServletRequestListener監聽器

  1. 作用:監聽Request創建或者銷毀,即Request對象的生命周期監聽
  2. 相關方法:
    • void requestInitialized(ServletRequestEvent sre):創建request對象時觸發
    • void requestDestroyed(ServletRequestEvent sre):銷毀request對象時觸發
  3. 可以用來監控某個IP訪問我們網站的頻率,做日誌記錄,或者訪問資源的情況等。

應用實例

  1. 創建監聽器:MyServletRequestListener
package com.listener;

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;

public class MyServletRequestListener implements ServletRequestListener {
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("MyServletRequestListener 監聽到request對象被創建 ");
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        System.out.println("記錄訪問日誌...");
        System.out.println("訪問IP= " + servletRequest.getRemoteAddr());
        System.out.println("訪問的資源= " + ((HttpServletRequest) servletRequest).getRequestURL());

    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("MyServletRequestListener 監聽到request對象被銷毀...");
    }
}
  1. hiServlet不做修改

  2. 配置監聽器:

<listener>
    <listener-class>com.listener.MyServletRequestListener</listener-class>
</listener>
  1. redeployTomcat,在瀏覽器訪問hiServlet,後臺輸出如下:

    (中間的session監聽可忽略)

    image-20221127191733329
  2. 訪問項目首頁面,後臺輸出如下:

    image-20221127192003350

2.6ServletRequestAttributeListener監聽器

  1. 作用:監聽Request屬性變化
  2. 相關方法
    • void attributeAdded(ServletRequestAttributeEvent srae):添加屬性時調用
    • void attributeReplaced(ServletRequestAttributeEvent srae):替換屬性時調用
    • void attributeRemoved(ServletRequestAttributeEvent srae):移除屬性時調用
  3. 使用方法和前面類似

2.7HttpSessionBindingListener感知監聽器

該監聽器是用來綁定數據的。如果一個對象實現了HttpSessionBindingListener介面,當這個對象被綁定到Session中或者從session中被刪除時,Servlet容器會通知這個對象,而這個對象在接收到通知後,可以做一些初始化或清除狀態的操作。

2.8HttpSessionActivationListener感知監聽器

HttpSessionActivationListener用於監控實現類本身,當實現類對象被添加到session屬性中後,session對象序列化(鈍化)前和反序列化(活化)後都會被執行

相應的方法:

  • sessionWillPassivate(HttpSessionEvent se): session鈍化前執行(session從記憶體到硬碟)
  • sessionDidActivate(HttpSessionEvent se):session活化後執行(session從硬碟到記憶體)

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # HTTPS server server { listen 443; server_name ************.com; ssl on; ssl_certificate cert/************.com.pem; ssl_certificate_key cert/******** ...
  • 摘要:在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡歷中脫穎而出成為最亮的那個崽呢? 本文分享自華為雲社區《【一行代碼秒上雲】連夜自建網站背刺我的求職對手們 !》,作者:AppCloud小助手。 前言 在競爭如此激烈的當下,作為一名IT新人,怎麼才能讓HR眼前一亮,從萬千簡 ...
  • 平常對於星號的應用場景用得少是不需要瞭解太多用法的。不過,學編程的過程少不了要去閱讀優秀的源代碼庫,也就時常會對星號 * 的貿然出現和用途感到困惑,所以今天就讓你們好好瞭解一下會有哪些用法。 ...
  • 起初data.txt文件是這樣的 # 一直打開文件但卻不關閉文件會導致記憶體溢出 # 在python,使用open函數, # 可以打開一個已經存在的文件,或者創建一個新文件, # 語法如下: open(name, mode) # name: 是要打開的目標文件名的字元串(可以包含文件所在的具體路徑)。 ...
  • 您好,我是湘王,這是我的博客園,歡迎您來,歡迎您再來~ Spring Security使用MySQL保存cookie記錄雖然方便,但是目前更多的主流互聯網應用都是用NoSQL來保存非業務數據的,Spring Security也應該可以實現這個功能。之前Spring Security官方並不支持使用N ...
  • 1,首先創建一個普通的Java項目 2,將項目變為web項目 在項目上單機右鍵-->選擇 Add FrameWorks Support 選擇第一項 web application-->OK 此時項目已經變為web項目,已經可以添加tomcat運行,但是一般web項目都會使用maven管理,所以可以添 ...
  • 代碼1 class Base { public: Base(int data=10):ma(data){ cout<<"Base()"<<endl; } void show(){cout<<"Base Show()"<<endl;} void show(int){cout<<"Base Show(i ...
  • 7. Spring整合Drools 全套代碼及資料全部完整提供,點此處下載 7.1 Spring簡單整合Drools 在項目中使用Drools時往往會跟Spring整合來使用。具體整合步驟如下: 第一步:創建maven工程drools_spring並配置pom.xml <?xml version=" ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...