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

完结撒花~~~~~~

原文地址:https://www.cnblogs.com/eco-just/p/7816632.html