zoukankan      html  css  js  c++  java
  • Javaweb统计在线人数的小栗子

    最近在学习Javaweb相关的内容(不黑不吹之前对web开发零基础),下面通过一个统计在线人数的小栗子讲讲Servlet监听器吧

    开发环境 eclipse  tomcat 7

    先说说这个小栗子的构思:

            首先要考虑的就是通过什么方式能够统计在线人数?很容易想到可以通过session来统计在线人数为什么不是request呢?因为request在请求结束时即服务器返回资源时就被销毁了,也就是说request的作用域不足以用以统计在线人数。服务器在第一次接受一个用户请求时会给该用户分配一个sessionid在有效期结束后或是用户主动关闭浏览器一段时间后session会被销毁,所以用session来统计在线人数是合情合理的。

            接下来问题来了,知道了统计在线人数和session相关那么应该如何操作呢?下面说说Servlet监听器。

            Servlet监听器只要就是用来对Web应用进行监听和控制的,功能接近Java的GUI程序的监听器,可以监听由于Web应用程序状态改变而引起的Servlet容器产生的相应事件,然后作出处理。

           Servlet监听器分为Servlet上下文监听器,Http会话监听器,Servlet请求监听器。

           既然用到了Session那我们先来看看Session相关的监听器吧。查看Apache文档

           HttpSessionListener接口有两个方法对应的是session被创建和被销毁时调用的。定义一个监听器类实现HttpSessionListener接口代码如下所示

     1 package com.xiaoysec;
     2 
     3 import java.util.ArrayList;
     4 
     5 import javax.servlet.annotation.WebListener;
     6 import javax.servlet.http.HttpSessionEvent;
     7 import javax.servlet.http.HttpSessionListener;
     8 
     9 /**
    10  * Application Lifecycle Listener implementation class MyHttpSessionListener
    11  *
    12  */
    13 
    14 public class MyHttpSessionListener implements HttpSessionListener {
    15     private int numberCount = 0;
    16 
    17     /**
    18      * Default constructor.
    19      */
    20     public MyHttpSessionListener() {
    21         // TODO Auto-generated constructor stub
    22     }
    23 
    24     /**
    25      * @see HttpSessionListener#sessionCreated(HttpSessionEvent)
    26      */
    27     public void sessionCreated(HttpSessionEvent arg0) {
    28         // TODO Auto-generated method stub
    29         numberCount++;
    30         arg0.getSession().getServletContext()
    31                 .setAttribute("numberCount", numberCount);
    32     }
    33 
    34     /**
    35      * @see HttpSessionListener#sessionDestroyed(HttpSessionEvent)
    36      */
    37     public void sessionDestroyed(HttpSessionEvent arg0) {
    38         // TODO Auto-generated method stub
    39         numberCount--;
    40         arg0.getSession().getServletContext()
    41                 .setAttribute("numberCount", numberCount);
    42         ArrayList<Userinfo> userlist = (ArrayList<Userinfo>) arg0.getSession()
    43                 .getServletContext().getAttribute("userlist");
    44         if (SessionUtil.getUsersessionid(userlist, arg0.getSession().getId()) != null) {
    45             userlist.remove(SessionUtil.getUsersessionid(userlist, arg0
    46                     .getSession().getId()));
    47         }
    48     }
    49 
    50 }

    在Session被创建时numberCount++,在被销毁时numberCount--。这样,一个简单的在线人数统计功能就实现了,接下来完善一下,如果想看到客户端的ip信息又该怎么办呢?首先还是思考如何获取用户信息,很容易想到可以通过request获取客户端的信息。

        定义一个封装用户信息的Javabean,代码如下:

        

     1 package com.xiaoysec;
     2 
     3 public class Userinfo {
     4     private String sessionid;
     5     private String ip;
     6     private String recenttime;
     7 
     8     public String getSessionid() {
     9         return sessionid;
    10     }
    11 
    12     public void setSessionid(String sessionid) {
    13         this.sessionid = sessionid;
    14     }
    15 
    16     public String getIp() {
    17         return ip;
    18     }
    19 
    20     public void setIp(String ip) {
    21         this.ip = ip;
    22     }
    23 
    24     public String getRecenttime() {
    25         return recenttime;
    26     }
    27 
    28     public void setRecenttime(String recenttime) {
    29         this.recenttime = recenttime;
    30     }
    31 
    32 }

     定义一个类MyServletRquestListener实现ServletRequestListener接口,在该接口中定义了一个requestInitialized方法,在服务器端接收到客户端的请求时被调用,

     代码如下:

     1 package com.xiaoysec;
     2 
     3 import java.text.SimpleDateFormat;
     4 import java.util.ArrayList;
     5 import java.util.Date;
     6 
     7 import javax.servlet.ServletRequestEvent;
     8 import javax.servlet.ServletRequestListener;
     9 import javax.servlet.annotation.WebListener;
    10 import javax.servlet.http.HttpServletRequest;
    11 
    12 public class MyServletRquestListener implements ServletRequestListener {
    13     private ArrayList<Userinfo> userlist; // 在綫用戶的list
    14 
    15     @Override
    16     public void requestDestroyed(ServletRequestEvent arg0) {
    17         // TODO Auto-generated method stub
    18 
    19     }
    20 
    21     /**
    22      * 在初始化request的初始化中判斷是否存在user的信息(sessionid)如果不存在的話就保存在userlist中
    23      */
    24     @Override
    25     public void requestInitialized(ServletRequestEvent arg0) {
    26         userlist = (ArrayList<Userinfo>) arg0.getServletContext().getAttribute("userlist");
    27         if(userlist==null)
    28             userlist = new ArrayList<Userinfo>(); 
    29         HttpServletRequest req = (HttpServletRequest) arg0.getServletRequest();
    30         String sessionid = req.getSession().getId();
    31         if (SessionUtil.getUsersessionid(userlist, sessionid) == null) {
    32             Userinfo user = new Userinfo();
    33             user.setIp(req.getRemoteAddr());
    34             user.setSessionid(sessionid);
    35             user.setRecenttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    36                     .format(new Date()));
    37             userlist.add(user);
    38         }
    39         arg0.getServletContext().setAttribute("userlist", userlist);
    40     }
    41 
    42 } 

     接着写一个SessionUtil类实现了getUsersessionid方法,代码如下:

     1 package com.xiaoysec;
     2 
     3 import java.util.ArrayList;
     4 
     5 public class SessionUtil {
     6     public static Object getUsersessionid(ArrayList<Userinfo> userlist,String sessionid) {
     7          for(int i=0;i<userlist.size();i++){
     8               Userinfo info = userlist.get(i);
     9               if(userlist.get(i).getSessionid().equals(sessionid)) //表示当前的sessionid用户存在于用户list中不需要
    10                   return info;
    11          }
    12         return null;
    13     }
    14 
    15 }

    在getUsersessionid中参数为userlist和sessionid,通过一个循环判断sessionid所指的用户是否在userlist中如果在的话就返回用户信息info,如果不在的话就返回null并在MyServletRquestListener的31行处添加进userlist。

    最后是界面jsp展示

     1 <%@ page language="java" contentType="text/html; charset=UTF-8"
     2     pageEncoding="UTF-8"%>
     3 <%@  page import="java.util.*"%>
     4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     5 <html>
     6 <head>
     7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     8 <title>Insert title here</title>
     9 </head>
    10 <body>
    11     当前用户在线人数<%= application.getAttribute("numberCount") %><br/>
    12     <%
    13         ArrayList<com.xiaoysec.Userinfo> userlist = (ArrayList<com.xiaoysec.Userinfo>)request
    14                 .getServletContext().getAttribute("userlist");
    15     if(userlist!=null){
    16         for (int i=0;i<userlist.size();i++) {
    17             com.xiaoysec.Userinfo info = userlist.get(i);
    18     %>
    19     ip:<%=info.getIp()%><br /> 
    20     recentTime:<%=info.getRecenttime()%><br/>
    21     sessionid:<%=info.getSessionid()%><br/>
    22     <%
    23         }}
    24     %>
    25 </body>
    26 </html>

    总结:通过这个小栗子只是对Servlet监听器有一个小小的了解,还是需要多看源码,理解过程,多代码,多思考,多总结。

        

  • 相关阅读:
    BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
    BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
    HDU 1423 Greatest Common Increasing Subsequence ——动态规划
    BZOJ 3309 DZY Loves Math ——莫比乌斯反演
    POJ 1038 Bugs Integrated, Inc. ——状压DP
    POJ 3693 Maximum repetition substring ——后缀数组
    POJ 2699 The Maximum Number of Strong Kings ——网络流
    POJ 2396 Budget ——有上下界的网络流
    BZOJ 4650 [Noi2016]优秀的拆分 ——后缀数组
    源码安装python
  • 原文地址:https://www.cnblogs.com/xiaoysec/p/4245650.html
Copyright © 2011-2022 走看看