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
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...