Listener
- Listener 是 Web 的三大組件之一:
- Servlet(控制器)
- Filter(過濾器)
- Listener(監聽器):可以 監聽 JavaWeb 中的三大域對象:HttpServletRequest、HttpSession、ServletContext (創建和銷燬),一旦被監視的對象發生相應的變化,應該採取相應的操作。
- Listener 的應用場景:歷史訪問次數、統計在線人數、系統啓動時初始化配置信息等。
1. ServletContextListenner
- 監聽器在 Web 開發中使用的比較少,監聽器的使用方式都差不多,這裏使用的是監聽器中使用率最高的 ServletContextListenner。使用這個監聽器可以在項目啓動和銷燬的時候做一些事情。例如,在項目啓動的時候加載配置文件。
a. 使用步驟
- 創建一個普通類,實現 ServletContextListenner。
- 重寫抽象方法:
監聽 ServletContext 創建;
監聽 ServletContext 銷燬。
- 配置:
web.xml 版本
註解版本
- 監聽 HttpServletRequestListener,用戶每次訪問時,觸發創建。
- 監聽 HttpSessionListener,瀏覽器建立會話時,觸發創建。
i. xml 版本
package com.company;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("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 {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("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 {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext 已經創建了...");
ServletContext servletContext = servletContextEvent.getServletContext();
String configLocation = servletContext.getInitParameter("configLocation");
System.out.println("動態獲取配置文件名稱:" + configLocation);
}
@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 {
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 {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
ServletContext servletContext = session.getServletContext();
Integer number = (Integer) servletContext.getAttribute("number");
servletContext.setAttribute("number", number + 1);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
ServletContext servletContext = session.getServletContext();
Integer number = (Integer) servletContext.getAttribute("number");
servletContext.setAttribute("number", number - 1);
}
}
e. 測試
原文鏈接:https://qwert.blog.csdn.net/article/details/105756517