前言
要完成在线用户统计功能的监听器,需要实现如下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>
管理员密码: <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中
- 创建监听器,监听在线用户
- 创建在线统计页面,展示监听的在线用户信息