监听器Listener的关于统计在线人数的问题

在统计在线人数的时候,分为两种情况的统计,一种是统计访问该网站的人数(不登录),另外一种就是登录的人数。

首先在容器启动时,我们可以声明一个ServletContext对象,并通过setAttribute方法初始化访问人数为0,

第一种情况下,每当有浏览器访问网站的时候就会创建一个session,并调用HttpSessionListener的sessionCreated的方法对访问人数增一,在会话消亡时调用HttpSessionListener的sessionDestroyed来对访问人数减一,但是问题来了,我们可以知道会话的消亡只能通过两种方式,一种是等待其消亡时间到,另外一种就是使用session.invalidate()来手动使其消亡,而关闭浏览器并不能使session消亡,所以在关闭浏览器后,消亡时间前,是不会执行sessionDestroyed方法。后来想到用js来触发关闭浏览器的事件再交由servlet处理,然而,我们无法再前端区分用户是刷新还是关闭浏览器,所以还是无法完成我们的目标,只能借助session的超时来处理,但无法做到十分实时,只能将超时时间设置的短一些,同时使用空请求一直保持与后台交互。

第二种情况下,每当有用户登录,session就会添加一个键值对,可以利用HttpSessionAttributeListener的attributeAdded方法来对用户在线人数增一,在退出账户时调用attributeRemoved方法,但是如果用户直接浏览器退出,则仍然无法调用该方法,解决方法同上。

package Listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;

@WebListener
public class ListenerDemo implements ServletContextListener,
        HttpSessionListener, HttpSessionAttributeListener {
    // Public constructor is required by servlet spec
    public ListenerDemo() {
    }

    // -------------------------------------------------------
    // ServletContextListener implementation
    // -------------------------------------------------------
    public void contextInitialized(ServletContextEvent sce) {
      /* This method is called when the servlet context is
         initialized(when the Web application is deployed). 
         You can initialize servlet context related data here.
      */
        ServletContext application = sce.getServletContext();
        application.setAttribute("onlineCount", 0);
        application.setAttribute("userCount", 0);
        System.out.println((int)application.getAttribute("onlineCount"));
    }


    public void contextDestroyed(ServletContextEvent sce) {
      /* This method is invoked when the Servlet Context 
         (the Web application) is undeployed or 
         Application Server shuts down.
      */
    }

    // -------------------------------------------------------
    // HttpSessionListener implementation
    // -------------------------------------------------------
    public void sessionCreated(HttpSessionEvent se) {
      /* Session is created. */
        ServletContext application = se.getSession().getServletContext();
        int count = (int)application.getAttribute("onlineCount");
        ++count;
        System.out.println(count);   //如果不让IDEA自动打开浏览器,此处的在线人数正常
        application.setAttribute("onlineCount", count);
        
    }

    public void sessionDestroyed(HttpSessionEvent se) {
      /* Session is destroyed. */
        //之所以关闭浏览器人数未减少,是由于关闭浏览器后session是没有消亡,故不会执行此方法,只能通过设置消亡时长或手动,解决问题:利用js捕获关闭浏览器的事件才触发
        System.out.println("消亡");
        ServletContext application = se.getSession().getServletContext();
        int count = (int)application.getAttribute("onlineCount");
        --count;
        application.setAttribute("onlineCount", count);

    }

    // -------------------------------------------------------
    // HttpSessionAttributeListener implementation
    // -------------------------------------------------------

    public void attributeAdded(HttpSessionBindingEvent sbe) {
      /* This method is called when an attribute 
         is added to a session.
      */
        if(sbe.getName().equals("username")) {
            ServletContext application = sbe.getSession().getServletContext();
            int count = (int)application.getAttribute("userCount");
            ++count;
            application.setAttribute("userCount", count);
        }
    }

    public void attributeRemoved(HttpSessionBindingEvent sbe) {
      /* This method is called when an attribute
         is removed from a session.
      */
      //用户退出减一
    }

    public void attributeReplaced(HttpSessionBindingEvent sbe) {
      /* This method is invoked when an attibute
         is replaced in a session.
      */
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <error-page>
        <error-code>404</error-code>
        <location>/error.jsp</location>
    </error-page>
    <session-config>
        <session-timeout>30</session-timeout> <!--设置会话存活时间为30分钟 -->
    </session-config>
</web-app>

猜你喜欢

转载自www.cnblogs.com/chenloveslife/p/9125787.html