实现思路
通过监听ServletContext,ServletRequest,HttpSession来统计页面的访问人数。根据Session的创建方式,在切换另一个游览器时创建了新的Session,所以用了作用域更高的ServletContext来监听.在ServletContext中存放以用户ip为Key的Map。Value为Session的集合。在用户访问时把产生的ip和Session传入map里,Session销毁时,移出map中相关的数据。具体步骤如下:
1.创建ServletContext监听
@Component
public class ServletContextListener implements javax.servlet.ServletContextListener {
private Map<String, List<HttpSession>> userMap = new HashMap<>();
@Override
public void contextInitialized(ServletContextEvent sce) {
sce.getServletContext().setAttribute("userMap",userMap);
}
}
在监听中创建访问人数的mao集合,数据存入ServletContext中。
2.创建HttpSeesion监听
@Component
public class HttpSessionListener implements javax.servlet.http.HttpSessionListener {
/**
* session失效后执行
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//获取session
HttpSession session = se.getSession();
String ip = (String) session.getAttribute("ip");
//获取servletContext
ServletContext servletContext = session.getServletContext();
//获取userMap
Map<String, List<HttpSession>> userMap = (Map<String, List<HttpSession>>) servletContext.getAttribute("userMap");
List<HttpSession> sessions = userMap.get(ip);
//移除session
sessions.remove(session);
//如果sessionList的长度为0,说明没有以这个ip访问的用户已经下线,从user,map中移出ip。
if(sessions.size()==0){
userMap.remove(ip);
}else{
userMap.put(ip, sessions);
}
servletContext.setAttribute("userMap", userMap);
}
}
//session销毁的监听,在session销毁时,先从sessionList中移除Session,如果list长度为0则说明用户以及下线(基于不同的游览器可以产生的session),从用户map中删除。
3.ServletContest监听
@Component
public class RequestContextListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
ServletRequest servletRequest = sre.getServletRequest();
//获取ip,存入ServletContext
String ip = servletRequest.getRemoteAddr();
HttpServletRequest request = (HttpServletRequest) servletRequest;
//获取session
HttpSession session = request.getSession();
session.setAttribute("ip",ip);
//获取map集合
ServletContext servletContext = sre.getServletContext();
Map<String, List<HttpSession>> userMap = (Map<String, List<HttpSession>>) servletContext.getAttribute("userMap");
//获取sessionList
List<HttpSession> sessionList=userMap.containsKey(ip) ? userMap.get(ip) : new ArrayList<>();
if(!sessionList.contains(session)){
sessionList.add(session);
}
userMap.put(ip, sessionList);
//存入userMap
servletContext.setAttribute("userMap",userMap);
}
}
在有请求访问站点时,获取session,通过request获取用户路由地址。把地址存入session中.判断Map中是否存在相同的ip,如果没有创建lsessionList,把ip和lsessionLst存入userMap中。如果存在相同的ip,则获取sessionList,把session存入.最后在把数据保存在userMap中。
测试
设置session的过时时间为5秒。
index.html
<h1>
Hello World
</h1>
当前在线人数:
<span th:text="${application.userMap}" ></span>
<br>
<span th:text="${application.userMap.size()}" ></span>
以localhost:8080访问
![](https://img.haomeiwen.com/i14299013/43a5b2e4b2237055.png)
两个游览器以localhost:8080访问
![](https://img.haomeiwen.com/i14299013/7912933681cddd24.png)
一个游览器以localhost:8080访问一个以127.0.0.1:8080访问
![](https://img.haomeiwen.com/i14299013/580be031aedbfd7c.png)
等session过时再次访问
![](https://img.haomeiwen.com/i14299013/cf525b74bf058af9.png)
网友评论