• java监听器之实现在线人数显示


    在码农的世界里只有bug才能让人成长,The more bugs you encounter, the more efficient you will be!

    java中的监听器分为三种:ServletRequestListener、HttpSessionListener、ServletContextListener;

    ServletRequest--请求,在客户端对服务器发生请求(访问)时发生,请求一次发生一次(不考虑请求转发),

                   请求结束,该对象销毁;

    HttpSession--会话,单个用户在某段时间内(Tomcat默认为30min,可以设置),自第一次发生请求(访问)

                   时创建,直到过期,该对象销毁;

    ServletContext--上下文,该对象存在于服务器端,自服务器开启时创建,直到服务器关闭该对象销毁。

    那么,就有这样一个思路:一个用户持续对网站的访问,请求数会很多,但是该用户多次请求的Session却一

    直都是一个(唯一性)。我们可以在第一次访问时把Session对象的ID存到服务器(上下文),后面每一次请求的

    时候,我们可以检查,该请求的Session对象是否已经在服务器(上下文),如果在,说明这次请求和之前的某次

    请求是同一个用户,如果不在,那么将这个请求产生的新Session对象的ID存到服务器(上下文)。Session对象到

    期,自然就被销毁(可以看做用户长时间每活动,被迫下线了),那么将这个SessionID所在的整条信息删除,也

    就是可以看做,当前访问用户减少一个。其实除了多次请求产生的Session具有唯一性之外,发出请求的设备也是

    具有唯一性的,我们可以通过获得设备的IP进行标识。我们可以将这两个信息存到用户类中,每个用户对象都有这

    两个属性,并且是唯一的。

    1.ServletRequest监听器

     1 public class Requestlisen implements ServletRequestListener {
     2 
     3     public void requestDestroyed(ServletRequestEvent arg0) {
     4         // TODO Auto-generated method stub
     5 
     6     }
     7 
     8     public void requestInitialized(ServletRequestEvent arg0) {
     9         // TODO Auto-generated method stub
    10         System.out.println("-----request创建了-------");
    11         HttpServletRequest request = (HttpServletRequest) arg0
    12                 .getServletRequest();
    13         if (arg0.getServletContext().getAttribute("userlist") == null) {
    14             List<User> userlist = new ArrayList<User>();
    15             arg0.getServletContext().setAttribute("userlist", userlist);
    16         }
    17         List<User> userlist = (List<User>) arg0.getServletContext()
    18                 .getAttribute("userlist");
    19         String id = request.getSession().getId();
    20         User user = (User) Getuserbyid.finduser(userlist, id);
    21         if (user == null) {
    22             System.out.println("-----当前请求对象不存在于服务器-----");
    23             System.out.println("------将当前用户添加到服务器-----");
    24             User newuser = new User();
    25             newuser.setIp(request.getRemotePort() + "");
    26             newuser.setSessionid(id);
    27             userlist.add(newuser);
    28             arg0.getServletContext().setAttribute("userlist", userlist);
    29         }
    30     }
    31 }

    在这个监听器中,我们只需要在请求初始化的时候,根据这个请求产生的SessionID判断,当前SessionID

    所属的用户是否存在于服务器用户列表中,如果不存在,就新建一个用户(包含IP和SessionID信息),并

    存入服务器用户列表。当然当第一个用户访问服务器时,用户列表是空的,为了防止出现空指针异常,我们

    要在此时为服务器创建一个用户列表。

    2.HttpSession监听器

     1 public class Sessionlisten implements HttpSessionListener {
     2     private int count;
     3     public void sessionCreated(HttpSessionEvent arg0) {
     4         // TODO Auto-generated method stub
     5         System.out.println("-----新建会话-----");
     6         count++;
     7         arg0.getSession().getServletContext().setAttribute("usercount", count);
     8     }
     9     public void sessionDestroyed(HttpSessionEvent arg0) {
    10         // TODO Auto-generated method stub
    11         count--;
    12         arg0.getSession().getServletContext().setAttribute("usercount", count);
    13         System.out.println("-----会话销毁-----");
    14         List<User> userlist = (List<User>) arg0.getSession()
    15                 .getServletContext().getAttribute("userlist");
    16         String id = arg0.getSession().getId();
    17         User user = (User) Getuserbyid.finduser(userlist, id);
    18         userlist.remove(user);
    19         arg0.getSession().getServletContext()
    20                 .setAttribute("userlist", userlist);
    21         System.out.println("-------当前用户从服务器删除-----");
    22     }
    23 }

    在Session对象监听器中,当一个会话创建时(有新用户访问),我们设置访问量加1,

    当一个会话销毁时,表示一个用户掉线了,没有对服务器进行访问了,那么访问量减1,并且我们通过当

    前会话ID获得这个用户,并且将这个用户从服务器用户列表删除。

    下面是根据SessionID查询用户的功能类:

     1 public class Getuserbyid {
     2     public static Object finduser(List<User> userlist,String id){
     3         if(userlist!=null){
     4             for(User user:userlist){
     5                 if(user.getSessionid().equals(id)){
     6                     return user;
     7                 }
     8             }
     9         }
    10         return null;
    11     }
    12 }

    因为Session对象销毁时之前,这个Session对象所属的用户信心必定是早就存到上下文对象中了(服务器用

    户列表),那么自然是存在的,我们就根据SessionID这个字段来遍历所有用户的SessionID属性,从而找到

    这个用户,将其从列表删除。

    注意:监听器创建之后要进行注册,不然是不能够起到监听作用的。还有就是不要忘记写一个页面来展示一下

    存在于用户列表的所有用户信息。

     1   <%
     2      List<User> userlist=(List<User>)request.getServletContext().getAttribute("userlist");
     3   %>
     4     在线人数:<%=userlist.size() %><br>
     5     
     6   <%
     7      if(userlist!=null){
     8          for (User user :userlist){
     9   %>
    10              IP地址:<%=user.getIp() %>----sessionId:<%=user.getSessionid() %><br>
    11 
    12   <%
    13     }}
    14   %>
    在线人数:2
    IP地址:0:0:0:0:0:0:0:1----sessionId:18166147D09F290A25924ACF9753E19D  同一台电脑两个浏览器访问,IP自然相同
    IP地址:0:0:0:0:0:0:0:1----sessionId:43C373670AF88EE244CBF7E6585F2285

    完结撒花~~~~~~

  • 相关阅读:
    洛谷7月月赛 B 题解
    undone
    树剖学习
    关于两周后noip---小计划
    线段树技巧练习--GSS1
    链式前向星存图及注意要点
    错题集合
    树上差分问题
    2020暑假学习内容整理及后续计划
    安利大佬博客
  • 原文地址:https://www.cnblogs.com/eco-just/p/7816632.html
Copyright © 2020-2023  润新知