springboot+thymeleaf实现一个简单的监听在线人数功能

news/2024/11/14 14:54:17/

功能步骤:

1. 当用户访问登录页面时,Logincontroller的showLoginForm方法被调用,返回登录页面的视图名字。

2. 用户提交表单,调用LoginController的login方法。

3.login方法

4.登录验证通过,home方法会被调用,该方法从会话中取在线人数,并添加到模型中,之后返回home。

5.OnlineUserCounterListener是一个实现了HttpSessionListener接口的监听器,它监听会话(session)的创建和销毁事件。

每次登录验证通过,也就是登录成功,会话(session)都会被创建,sessionCreated方法会被调用,这样就可以直接通过session来获取在线人数,但是为了更方便管理和操作在线用户的信息,可以再创建一个OnlineUserManager 类:

功能:添加用户,删除用户,统计在线人数,还可以拥有其他功能比如,比如获取在线用户的详细信息,这个可以根据实际需要再进行完善。

import java.util.HashSet;
import java.util.Set;/*** @author a1002*/
public class OnlineUserManager {private static Set<String> onlineUsers = new HashSet<>();public static void addUser(String username) {onlineUsers.add(username);}public static void removeUser(String username) {onlineUsers.remove(username);}public static int getOnlineCount() {return onlineUsers.size();}
}

OnlineUserManager中获取在线人数,并将其存储在ServletContext中,以便全局访问。

@Overridepublic void sessionCreated(HttpSessionEvent se) {ServletContext servletContext = se.getSession().getServletContext();int onlineCount = OnlineUserManager.getOnlineCount();servletContext.setAttribute("onlineCount", onlineCount);}

为了使OnlineUserCounterListener生效,需要将其注册为一个监听器。在配置类AppConfig中,使用@Bean注解将OnlineUserCounterListener实例化,并将其返回。这样,它就会被自动注册到Spring的上下文中。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {@Beanpublic OnlineUserCounterListener onlineUserCounterListener() {return new OnlineUserCounterListener();}
}

从以上步骤可以得出:OnlineUserManager是一个用户全局的用户管理,同时,里面存储的数据会在每一个session被创建的时候()同步到一个全局的servletContext中。

每当用户登录验证成功后,OnlineUserManager中的用户会加1,session中的onlineCount也会更新,并被发送给home.html用来在页面上显示数据。

扩展:

登录过程中通常会创建一个会话(session)。会话是在用户与应用程序之间建立的一个状态保持机制,用于跟踪用户的登录状态和存储相关的会话数据。

在Web应用程序中,会话是通过使用会话ID来实现的。当用户成功登录时,服务器会为该用户创建一个唯一的会话ID,并将其与用户的会话数据关联起来。会话ID可以通过Cookie、URL重写或其他方式发送到客户端,并在后续的请求中被客户端发送回服务器。

服务器可以根据接收到的会话ID识别特定的会话,并根据需要访问会话数据。在登录过程中,常见的做法是将用户的身份信息存储在会话中,存储用户对象在会话中的好处是,它允许在用户的后续请求中访问用户的相关信息,而无需重复进行身份验证。通过使用会话,在用户与应用程序之间保持登录状态,并且可以在需要时从会话中检索用户信息,以便进行授权、个性化设置或其他操作。


但是以上步骤还是存在一个问题,如果只删除了某个用户的会话(session),而未在OnlineUserManager 中更新相应的在线用户列表,可能会导致数据不一致的问题。

在典型的应用程序中,会话的创建和销毁通常是由应用程序框架或服务器自动处理的。当会话过期、用户注销或其他条件满足时,会话将被销毁。在这种情况下,会自动触发 HttpSessionListener 监听器中的 sessionDestroyed 方法,所以我们可以在该方法中更新 OnlineUserManager 中的在线用户列表。

@Overridepublic void sessionDestroyed(HttpSessionEvent se) {HttpSession session = se.getSession();User user = (User) session.getAttribute("user");if (user != null) {// 从在线用户列表中移除该用户OnlineUserManager.removeUser(user.getUsername());}}

当然,也还有一些示例,比如

  1. 使用过期机制:在会话创建时设置合适的会话过期时间。这样,当会话超过一定时间没有活动时,它将自动销毁,并触发 HttpSessionListener 中的 sessionDestroyed 方法。

  2. 错误处理和异常情况处理:在应用程序中处理会话销毁的异常情况。例如,通过定期检查会话是否仍然有效,并在发现无效会话时进行清理和更新。

扩展ServletContext 是一个在整个应用程序范围内共享数据的对象,它可以存储和获取全局的数据。

当在线人数发生变化时,可以将最新的在线人数存储在 ServletContext 中,以便在整个应用程序范围内共享这个数据。同时,在每个会话中,也可以将当前的在线人数存储在会话的属性中,以便在该会话的请求中访问和使用。

通过将在线人数存储在 ServletContext中,可以在整个应用程序中共享这个数据。而将在线人数存储在会话中,则可以在每个会话的请求中方便地获取并使用这个数据。

ServletContext 和会话(session)是不同的范围和生命周期的对象。ServletContext 是在应用程序启动时创建的,可以在整个应用程序的生命周期内共享数据。而会话是在用户与应用程序之间建立的,用于跟踪用户的状态和存储相关的会话数据。

所以,ServletContext 存储的在线人数是全局的,而会话中存储的在线人数是特定会话的状态。

这也就是上述补充的步骤中所在意的问题。


如果大家还有什么问题或者是发现还存在一些bug,都可以在评论区进行讨论,当然,如果应用到实际开发中的话,我这些东西是绝对不够用的


效果展示(页面有些拉,将就着看吧)

直接输入:http://localhost:8080/login

会跳转到:http://localhost:8080/home

之后再多开几个登录账号,但是如果账号与之前的有重复的话,这个是不计入在线人数中的。

登录不同的账号,进入主页都会发现在线人数会加1.


http://www.ppmy.cn/news/1440066.html

相关文章

# IDEA2019 如何打开 Run Dashboard 运行仪表面板

IDEA2019 如何打开 Run Dashboard 运行仪表面板 段子手168 1、依次点击 IDEA 上面工具栏 —> 【View】 视图。 —> 【Tool Windows】 工具。 —> 【Run Dashboard】 运行仪表面板。 2、如果 【Tool Windows 】工具包 没有 【Run Dashboard】 运行仪表面板 项 依次…

C++ map和set的应用

1. 关联式容器 我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、 forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身。那什么是关联式容器&#xff1f;它…

Elasticsearch 精确查询:术语查询、多术语查询、主键查询、范围查询、存在查询、前缀查询、正则查询与通配符查询

为了深入理解Elasticsearch的各种精确查询方法&#xff0c;我们将通过一系列示例来演示术语查询、多术语查询、主键查询、范围查询、存在查询、前缀查询、正则查询和通配符查询的应用场景。首先&#xff0c;我们为示例准备一组数据&#xff1a; POST person/_doc/1 {"id&…

【Node.js】03 —— HTTP 模块探索

&#x1f31f;Node.js之HTTP模块探索✨ &#x1f31f;引言 在网络编程中&#xff0c;HTTP协议无处不在。在Node.js的世界里&#xff0c;我们可以通过内置的http模块来轻松创建HTTP服务器和客户端&#xff0c;实现数据的接收和发送。今天就让我们一起打开这扇门&#xff0c;探索…

05_Scala运算符

文章目录 **1.Scala运算符****2.scala中没有 --等语法****3.逻辑运算符和Java完全相同****4.scala认为万物皆对象** 1.Scala运算符 Scala底层 使用的是equals() 程序员比较两个量的时候&#xff0c;谁来没事比较内存地址&#xff1f; Java中引用数据类型比较地址&#xff0…

人工智能对数据分析领域的影响是什么?

人工智能&#xff08;AI&#xff09;对数据分析领域的影响深远且不断演进。这一领域的技术革新和应用拓展正在推动数据分析从传统的基于规则的方法转变为基于机器学习和深度学习的自动化方法。 人工智能极大地提高了数据分析的效率和准确性。传统的数据分析通常依赖于分析师的…

13 c++版本的五子棋

前言 呵呵 这大概是 大学里面的 c 五子棋了吧 有一些 面向对象的理解, 但是不多 这里 具体的实现 就不赘述, 仅仅是 发一下代码 以及 具体的使用 然后 貌似 放在 win10 上面执行 还有一些问题, 渲染的, 应该很好调整 五子棋 #include<Windows.h> #include<io…

网页提示语闪太快的定位问题(selenium)

selenium UI自动化时&#xff0c;提示语闪太快&#xff0c;导致无法获取元素的问题 解决办法 步骤一&#xff1a; F12---》控制台输入debugger 步骤二&#xff1a;对于需要定位的部分&#xff0c;在控制台的debugger处回车&#xff0c;可以定住页面 步骤三&#xff1a;正常定…