Listener 監聽器的簡述與應用


Listener

  • Listener 是 Web 的三大組件之一:
    • Servlet(控制器)
    • Filter(過濾器)
    • Listener(監聽器):可以 監聽 JavaWeb 中的三大域對象:HttpServletRequest、HttpSession、ServletContext (創建和銷燬),一旦被監視的對象發生相應的變化,應該採取相應的操作。
  • Listener 的應用場景:歷史訪問次數、統計在線人數、系統啓動時初始化配置信息等。

1. ServletContextListenner

  • 監聽器在 Web 開發中使用的比較少,監聽器的使用方式都差不多,這裏使用的是監聽器中使用率最高的 ServletContextListenner。使用這個監聽器可以在項目啓動和銷燬的時候做一些事情。例如,在項目啓動的時候加載配置文件。

a. 使用步驟

  1. 創建一個普通類,實現 ServletContextListenner。
  2. 重寫抽象方法:
    監聽 ServletContext 創建;
    監聽 ServletContext 銷燬。
  3. 配置:
    web.xml 版本
    註解版本
  • 監聽 HttpServletRequestListener,用戶每次訪問時,觸發創建。
  • 監聽 HttpSessionListener,瀏覽器建立會話時,觸發創建。

i. xml 版本

package com.company;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener {

    // 監聽ServletContext創建
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經創建了...");
    }

    // 監聽ServletContext銷燬
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經銷燬了....");
    }
}
    <listener>
        <listener-class>com.company.MyListener</listener-class>
    </listener>

ii. 註解版本

package com.company;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyListener implements ServletContextListener {

    // 監聽ServletContext創建
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經創建了...");
    }

    // 監聽ServletContext銷燬
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經銷燬了....");
    }
}

b. 加載 Spring 環境

  • 可以在項目啓動時讀取配置文件。
    <!--全局配置參數-->
    <context-param>
        <param-name>configLocation</param-name>
        <param-value>words.properties</param-value>
    </context-param>
    
    <listener>
        <listener-class>com.company.MyListener</listener-class>
    </listener>
package com.company;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyListener implements ServletContextListener {

    // 監聽ServletContext創建
    /*
        ServletContextEvent 上下文事件對象,獲取ServletContext
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經創建了...");

        // 通過ServletContextEvent獲取上下文對象
        ServletContext servletContext = servletContextEvent.getServletContext();
        // 可以加載定義配置文件的名稱
        String configLocation = servletContext.getInitParameter("configLocation");
        System.out.println("動態獲取配置文件名稱:" + configLocation);
    }

    // 監聽ServletContext銷燬
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext 已經銷燬了....");
    }
}
  • 運行 Tomcat,控制檯輸出:
    在這裏插入圖片描述

2. 綜合案例:統計在線人數

a. 主要需求

  • 有用戶使用網站,在線人數 +1;用戶退出網站,在線人數 -1。

b. 技術分析

  • 使用 ServletContext 域對象存儲在線總人數。
  • 使用 ServletContextListener 監聽器,在項目啓動時,初始化總人數爲 0。
  • 使用 HttpSessionListener 監聽器,用戶訪問,人數 +1,用戶退出,人數 -1。
  • 使用 LogoutServlet 控制器,對當前會話的 Session 銷燬。

c. 需求分析

在這裏插入圖片描述

d. 代碼實現

i. index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>${NAME}</title>
</head>
<body>
<h3>Regino's Blog</h3>

<h5>在線人數:${applicationScope.number}</h5>
<a href="${pageContext.request.contextPath}/LogoutServlet">用戶退出</a>
</body>
</html>

ii. LogoutServlet

package com.company;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 銷燬Session
        request.getSession().invalidate();

        response.getWriter().write("logout");
    }
}

iii. InitNumberListener

package com.company;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class InitNumberListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        // 獲取上下文域對象
        ServletContext servletContext = servletContextEvent.getServletContext();
        // 初始化在線人數
        servletContext.setAttribute("number", 0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

iv. NumberChangeListener

package com.company;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class NumberChangeListener implements HttpSessionListener {

    // 會話建立,在線人數+1
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        // 獲取Session域對象
        HttpSession session = httpSessionEvent.getSession();
        // 獲取上下文域對象
        ServletContext servletContext = session.getServletContext();
        // 取出在線人數
        Integer number = (Integer) servletContext.getAttribute("number");
        // +1
        servletContext.setAttribute("number", number + 1);
    }

    // 會話銷燬,在線人數-1
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        // 獲取Session域對象
        HttpSession session = httpSessionEvent.getSession();
        // 獲取上下文域對象
        ServletContext servletContext = session.getServletContext();
        // 取出在線人數
        Integer number = (Integer) servletContext.getAttribute("number");
        // -1
        servletContext.setAttribute("number", number - 1);
    }
}

e. 測試


原文鏈接:https://qwert.blog.csdn.net/article/details/105756517

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章