• 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监听器有一个小小的了解,还是需要多看源码,理解过程,多代码,多思考,多总结。

        

  • 相关阅读:
    ubuntu 20 配置phpmyadmin 403 问题
    【前端开发】常见的动画库
    【前端开发】一些有趣的操作
    【前端开发】基于vue+element开发的bpm流程设计器
    react中ref的3种绑定方式
    【Android】为什么必须在主线程中执行UI操作?
    ViewModel与LiveData如何监听数据变化更新试图
    android Loader
    Promise与async/await:1、A函数调用B函数,A、B函数是否使用await的区别;2、B函数return new promise()与const res = new promise(); return res;的区别
    ES7 Reflect Metadata
  • 原文地址:https://www.cnblogs.com/xiaoysec/p/4245650.html
Copyright © 2020-2023  润新知