Listener经典案例-在线用户统计

news2024/11/15 10:43:51

前言

 要完成在线用户统计功能的监听器,需要实现如下3个接口。

  • ServletContextListener接口
    • 使用此接口的作用是:在应用初始化的时候向application中添加一个空的Set集合用来保存在线用户。
  • HttpSessionAttributeListener接口
    • 使用此接口的作用是:当用户登陆成功后,会向session中添加一个属性用来保存用户信息,这样就表示新用户登陆,之后把用户保存在在线用户列表中。
  • HttpSessionListener接口
    • 使用此接口的作用是:当用户注销后将用户信息从用户列表中删除。

关键代码

contextInitialized

public void contextInitialized(ServletContextEvent se) {
	//创建set,保存用户信息
	Set<Users> onLineUsers=new HashSet<Users>();
	application=se.getServletContext();
	application.setAttribute("onLineUsers", onLineUsers);
}

attributeAdded

	public void attributeAdded(HttpSessionBindingEvent se) {
		HttpSession session=se.getSession();
		//得到新用户
		Users user=(Users) session.getAttribute("user");
		//从application中取出在线用户列表
		Set<Users>  onLineUsers=(Set<Users>) application.getAttribute("onLineUsers");
		//把新用户放到集合中
		onLineUsers.add(user);				
	}

attributeRemoved

public void attributeRemoved(HttpSessionBindingEvent se) {
	//得到用户的注销信息
	Users logOutUser=(Users) se.getValue();
	//取出在线用户列表
	Set<Users>  onLineUsers=(Set<Users>) 							application.getAttribute("onLineUsers");
	onLineUsers.remove(logOutUser);
		
	}

sessionDestroyed

public void sessionDestroyed(HttpSessionEvent se) {
	//得到注销用户的session信息
	HttpSession session=se.getSession();
	//得到新用户的信息
	Users logOutUser=(Users) session.getAttribute("user");
	Set<Users>  onLineUsers=(Set<Users>) 							application.getAttribute("onLineUsers");
	onLineUsers.remove(logOutUser);
	}

案例实现

第一步:创建一个JavaWeb项目,配置pom.xml和web.xml

pom.xml

  <dependencies>
    <!--junit单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!--jdbc连接mysql数据库-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.21</version>
    </dependency>
    <!--servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!--lombok-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
      <scope>provided</scope>
    </dependency>
    <!--jstl-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

  </dependencies>
  <build>
    <finalName>litener</finalName>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
      </plugin>


      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.3.14.v20161028</version>
      </plugin>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
          <uriEncoding>UTF-8</uriEncoding>
          <server>tomcat7</server>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>Archetype Created Web Application</display-name>
</web-app>

第二步:创建展示和处理数据的JSP页面

onLineUsers.jsp

<%--
  Created by IntelliJ IDEA.
  User: 21038
  Date: 2024/9/19
  Time: 14:24
  To change this template use File | Settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<c:forEach items="${onLineUsers}" var="u">
  <li>${u}</li>
</c:forEach>
</ul>

</body>
</html>

第三步:创建对应的Servlet类

LoginServlet

package servlet;

import dao.UserDao;
import dao.impl.UserDaoImpl;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        UserDao userDao =new UserDaoImpl();
        HttpSession session =req.getSession();
        int i = userDao.selectUserByuserNameAndpassword(username, password);
        if (i==1){
            session.setAttribute("username",username);
            req.getRequestDispatcher("userPage").forward(req,resp);
        }else {
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
        }

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
}

登录页面Login.jsp

<%--
  Created by IntelliJ IDEA.
  User: 21038
  Date: 2024/9/19
  Time: 10:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="login" method="post">
    管理员用户名:<input type="text" name="username"><br>
    管理员密码:&nbsp;<input type="text" name="password"><br>
    <input type="submit" value="登录"><br>
</form>

</body>
</html>

这里演示的这些代码段都是对应连接了数据库的操作,这里展示只是为了演示统计在线用户功能的实现思路,完整代码我会在servlet-crud案例中提供 。

第四步:监听session中的用户,书写监听器类

OnLineUserListener

package listener;

import entity.User;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;
import java.util.ArrayList;
import java.util.List;

@WebListener
public class OnLineUserListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {
    ServletContext application;
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        List<String> onLineUsers =new ArrayList<>();
        application = servletContextEvent.getServletContext();
        application.setAttribute("onLineUsers",onLineUsers);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session =httpSessionBindingEvent.getSession();
        String username =(String) session.getAttribute("username");
        List<String> onLineUsers=(List<String>) application.getAttribute("onLineUsers");
        onLineUsers.add(username);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {

    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {

    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {

    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session= httpSessionEvent.getSession();
        String username= (String) session.getAttribute("username");
        List<String> onLineUsers= (List<String>) application.getAttribute("onLineUsers");
        onLineUsers.remove(username);
    }
}

演示效果

登录页面

登录成功页面:

查看在线用户数

此时只有root用户在线

关键点:

  • 创建登录页面
  • 创建对应的servlet将登录用户信息存在session中
  • 创建监听器,监听在线用户
  • 创建在线统计页面,展示监听的在线用户信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2151979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【经验技巧】IBIS AMI模型眼图仿真问题探讨

最近&#xff0c;有同事问我&#xff1a;“拿到供应商的IBIS AMI模型&#xff0c;怎么判断是否可以进行应力&#xff08;统计&#xff09;眼图的仿真呀&#xff1f;如果不能进行&#xff0c;又怎么判断结果是瞬态仿真呢&#xff1f;” 不得不说&#xff0c;这的确是一个不错的话…

VMware虚拟机密码忘记了怎么办

1.首先&#xff0c;启动系统&#xff0c;进入开机界面&#xff0c;在界面中按“e”进入编辑界面 2.进入编辑界面&#xff0c;使用键盘上的上下键把光标往下移动&#xff0c;找到以““Linux16”开头内容所在的行数”&#xff0c;在行的最后面输入&#xff08;最好把前面的语言改…

JVM 调优篇8 调优案例6- 计算合理设置内存大小

一 jmap查看堆结构配置 1.1 逻辑流程 # 查看进程ID jps -l # 查看对应的进程ID的堆内存分配 jmap -heap 3725 1.2 案例演示 1.代码 public class AdaptiveSizePolicyTest {public static void main(String[] args) {try {Thread.sleep(1000000);} catch (Interrupted…

MFC-基础架构

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天讲解MFC的基础架构 概述 介绍&#xff1a;MFC&#xff08;Microsoft Foundation Classes&#xff09;是微软公司提供的一个类库&#xff0c;用于在 Windows 操作系统下进行 C 应用程序开发MFC把Windows SDK API函…

一堆让你眼界大开的实用工具网站——搜嗖工具箱

和图书 https://www.hetushu.com/ 一个好用的免费看小说网站。和图书是一个提供各种热门电子书,书籍,小说免费在线阅读的网站&#xff0c;涵盖网游、玄幻、穿越、科幻、仙侠、都市、武侠、历史、竞技、军事灵异等多个种类的小说。在这个网站看小说最大的感触简单干净&#xff…

数据标注——AI智能时代的关键之钥

洞见AI+专题 篇首语 在这个充满无限可能的时代,人工智能正以前所未有的速度改变着我们的世界。从日常生活的便利到行业效率的飞跃,AI技术的应用几乎无处不在。在银行业务中,同样可以看到AI带来的巨大潜力。本专题旨在展示农业银行科技部门在AI技术应用上的最新探索与实践成…

力扣之178.分数排名

1. 178.分数排名 1.1 题干 表: Scores -------------------- | Column Name | Type | -------------------- | id | int | | score | decimal | -------------------- id 是该表的主键&#xff08;有不同值的列&#xff09;。 该表的每一行都包含了一场比赛的分数。Score 是…

Docker+PyCharm远程调试环境隔离解决方案

DockerPyCharmMiniconda实现深度学习代码远程调试和环境隔离 本文详细介绍了如何在局域网环境下&#xff0c;利用Docker、PyCharm和Miniconda构建一个高效的深度学习远程调试平台。首先在服务器&#xff08;server&#xff09;上&#xff0c;通过Docker构建包含不同CUDA环境的镜…

MCS-51汇编

伪指令&#xff1a; EQU: Equal&#xff0c;定义常量 COUNT EQU 10H ; 定义一个符号名COUNT&#xff0c;其值为10H DELAY EQU 500 ; 定义一个符号名DELAY&#xff0c;其值为500 数据传送&#xff1a; MOV: MOVE&#xff0c;传送数据 MOVC: 算术运算&#xff1a; 跳转…

详解npm源及其使用方法

详解npm源及其使用方法 npm源是一个用于存储和提供npm包的服务器地址&#xff0c;npm在安装包时会通过这个源地址下载对应的依赖包。默认情况下&#xff0c;npm使用官方的npm源&#xff08;https://registry.npmjs.org/&#xff09;&#xff0c;该源存储了海量的Node.js开源包…

Android Studio 汉化教程,直接授人以渔,又菜又爱学英语还不好,不愧是我

Android Studio 汉化教程,直接授人以渔 查看使用的 Android Studio 版本号 当前版本号&#xff1a;241.18034.62.2412.12266719 打开官网插件地址 插件地址选择对应版本进行下载 版本怎么选&#xff1f; 我的版本号 241.18034.62.2412.12266719选择的版本号只有前三位对应的…

【JAVA开源】基于Vue和SpringBoot的网上超市系统

本文项目编号 T 037 &#xff0c;文末自助获取源码 \color{red}{T037&#xff0c;文末自助获取源码} T037&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

全国31省对外开放程度、经济发展水平、政府干预程度指标数据(2000-2022年)

旨在分析2000-2022年间中国31个省份的对外开放程度、经济发展水平和政府干预程度&#xff0c;探讨其背后的动因与影响。 2000年-2022年 全国31省对外开放程度、经济发展水平、政府干预程度指标数据https://download.csdn.net/download/2401_84585615/89478612 数据概览 对外…

Hexo博客私有部署Twikoo评论系统并迁移评论记录(自定义邮件回复模板)

部署 之前一直使用的artalk&#xff0c;现在想改用Twikoo&#xff0c;采用私有部署的方式。 私有部署 (Docker) 端口可以根据实际情况进行修改 docker run --name twikoo -e TWIKOO_THROTTLE1000 -p 8100:8100 -v ${PWD}/data:/app/data -e TWIKOO_PORT8100 -d imaegoo/twi…

英集芯IP5912:集成开关充电功能的低功耗8位POWER MCU芯片

英集芯IP5912是一款功能丰富的、集成了降压充电管理功能的8位MCU芯片&#xff0c;它内置了一个5V输入的同步降压充电DC-DC&#xff0c;功率管也是内置的&#xff0c;同时提供最大1.5A的充电电流。封装方式采用SOP16&#xff0c;方案应用时只需要很少的外围器件&#xff0c;就可…

Java面试篇基础部分-ReentrantLock详解(二)

Lock 接口的主要方法 void lock():给对象加锁,如果锁没有被其他线程使用,则当前线程获取到这个锁;如果锁正在被其他线程持有,则将禁用当前线程,直到当前线程获取到锁。boolean tryLock():试图给对象进行加锁操作,如果锁没有被其他线程使用,则将获取到这个锁并且返回tr…

基于JAVA+SpringBoot+Vue的智能无人仓库管理

基于JAVASpringBootVue的智能无人仓库管理 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; 哈…

单样本Cellchat(V2)细胞通讯分析学习和整理

细胞通讯分析是一种研究不同细胞类型之间如何通过信号分子&#xff08;如配体和受体&#xff09;进行相互交流和调控的分析方法。它在揭示细胞间相互作用的机制&#xff0c;理解组织和器官如何协调运作方面具有重要意义。 细胞通讯分析的主要内容如下&#xff1a; 配体-受体相…

新品亮相|美格智能SLM530/SLM530P智能模组,助力金融新零售智慧升级

随着金融支付产业数字化与智能化不断推进&#xff0c;泛支付场景一体化解决方案成为行业发展的新趋势&#xff0c;从手持POS机到智能收款机&#xff0c;金融支付领域需要更快速、更精准、更安全的解决方案&#xff0c;加快推进数字化升级进程。 近期&#xff0c;美格智能正式发…

Github 2024-09-21Rust开源项目日报 Top10

根据Github Trendings的统计,今日(2024-09-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10Move项目1JavaScript项目1Deno: 现代JavaScript和TypeScript运行时 创建周期:2118 天开发语言:Rust, JavaScript协议类型:MIT Lic…