页面在线访问人数统计&&在线登录人数统计一

一、页面在线访问人数统计

OnlineSessionListener监听器(实现HttpSessionListener)接口来实现页面在线访问人数统计,当有用户访问到页面就会创建一个session,此时会触发public   void   sessionCreatedHttpSessionEvent   se)方法,如果session失效,此时会触发public   void   sessionDestroyedHttpSessionEvent   se)方法。在此方法里我们用OnlineList进行在线访问人数的统计。

public class OnlineList {
	private static final OnlineList onlineList = new OnlineList);
	private int maxSession;
	private int activeSession;

	private OnlineList)
    {
       
    }
	
    public static OnlineList getInstance)
    {
        return onlineList;
    }
    
    public void addSession){
    	activeSession++;
    	ifactiveSession>=maxSession){
    		maxSession=activeSession;
    	}
	}
    
    public void delSession){
    	ifactiveSession   >   0)    
    		activeSession--;  
    }
	   
	public  int getActiveSession){
		return activeSession;
	}
	
	public  int getmaxSession){
	  return maxSession;
	 }  
}

  

public class OnlineSessionListener implements HttpSessionListener {

	private OnlineList ol = OnlineList.getInstance);
	public void sessionCreatedHttpSessionEvent se) {
		ol.addSession);
	}

	public void sessionDestroyedHttpSessionEvent se) {
		 ol.delSession);
	}

}

二、在线登录人数统计  

用UserListener监听器(实现HttpSessionAttributeListener接口)来实现在线登录人数统计,当有用户添加到session中,监听器就调用public void valueBoundHttpSessionBindingEvent event)方法。如果有用户退出系统,监听器就调用public void valueUnboundHttpSessionBindingEvent event)方法。我们用UserList来统计用户信息

在UserList这个类的设计上,我们应用了单例(Singleton)设计模式,关于设计模式的知识,读者可以参看相关的书籍。UserList是一个单例类,所谓单例类,是指一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。单例类的一个最重要的特点是类的构造方法是私有的,从而避免了外部利用该类的构造方法直接创建多个实例。在代码的第8行,定义一个静态的常量userList,它表示了UserList类的一个对象。在UserList类加载的时候,这个对象就产生了。第11~14行,声明UserList类的构造方法为private,这是为了避免在外部使用UserList类的构造方法创建其对象。要注意的是,如果在类中不写构造方法,那么Java编译器就会为这个类提供一个默认的不带参数的公开的构造方法,这样,在外部就可以通过类的构造方法创建对象了,那么UserList也就不再是一个单例类了。既然UserList类的构造方法是私有的,那么在外部就不能用new去构造对象,于是在代码的第16~19行,定义了一个静态的方法getInstance),在这个方法中,返回在类加载时创建的UserList类的对象。因为getInstance)方法本身是静态的,所以可以直接通过类名来调用。
      那么为什么要将UserList设计成单例类呢?这是因为UserList类的对象是用于存储和获取在线用户的列表,而这个用户列表对于所有的页面来说都应该是同一个,所以将UserList类设计成单例类,这样,所有的类访问的就是同一个UserList对象了。
      代码的第9行,定义了一个私有的Vector类型的变量,在UserList类的构造方法中,对Vector类型的变量v进行了初始化,用于存放String类型的对象。注意,在这个地方没有使用ArrayList,是考虑到UserList对象可能会被多个线程同时访问,因为ArrayList不是同步的,而Vector是同步的,所以采用Vector来保存用户列表。

import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class UserListener implements HttpSessionAttributeListener {
 //用户登录身份证
    private String USERNAME;
    private UserList u1 = UserList.getInstance);   
   
    //判断用户是否存在
    public boolean IsExistString sfz)throws Exception
    {
        try
        {
           
          return u1.IsExistsfz);
        }
        catchException ex)
        {
            ex.printStackTrace);
            return false;
        }
    }
  
  
 public String getUSERNAME) {
  return USERNAME;
 }
 public void setUSERNAMEString username) {
  USERNAME = username;
 }
 public void attributeAddedHttpSessionBindingEvent event) {
  try{
  if"USERNAME".equalsevent.getName))){
   u1.addUserString)event.getValue));
  }
  }catchException e){
   e.printStackTrace);
  }
  
 }
 public void attributeRemovedHttpSessionBindingEvent event) {
  try{
  if"USERNAME".equalsevent.getName))){
   u1.RemoveUserString)event.getValue));
  }
  }catchException e){
   e.printStackTrace);
  }
  
 }
 public void attributeReplacedHttpSessionBindingEvent arg0) {
  // TODO Auto-generated method stub
  
 }
}

  

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class UserList {
 private static final UserList userList = new UserList);
    private Vector v = new Vector);
    private int maxUser;
   
    private UserList)
    {
        //v = new Vector);
    }
    public static UserList getInstance)
    {
        return userList;
    }
    //将用户登陆身份证保存到Vector中
    public void addUserString sfz) throws Exception
    {
        try{
           if  sfz != null&&!"".equalssfz))
           {
               if   v.indexOfsfz) >= 0)//判断是否已经存在
                   return ;                 
               //可能的操作
               //添加登录ID
               v.addElementsfz);
               ifgetUserCount)>maxUser){
                maxUser=getUserCount);
               }
           }
        }
         catchException ex)
        {
            ex.printStackTrace);  
        }
        finally{
        }
    }
   
    public boolean IsExistString sfz)throws Exception
    {
        try{
             if   v.indexOfsfz) >= 0)
                   return true;              
            return false;
        }
        catchException ex)
        {
           ex.printStackTrace);
            return false;
        }
    }
   
    //删除用户登录ID
    public void RemoveUserString sfz)throws Exception
    {
        try{
           if  sfz != null&&!"".equalssfz) )
           { 
              //修改数据库
              //移除用户登录ID
               v.removeElementsfz);
           }
        }
        catchException ex)
        {    
            ex.printStackTrace); //写日志
        }
        finally{
        }
    }
    //返回Vector枚举
    public Enumeration getUserList)
    {
        return v.elements);
    }
    //返回迭代器
    public Iterator getUserListItera){
     return v.iterator);
    }
    //返回在线人数
    public int getUserCount)
    {
        return v.size);
    }
    //返回在线人数峰值
    public int getMaxUser){
     return maxUser;
    }
}

  

最后在web-xml里 加入如下信息

 <listener>

     <listener-class>com.myxmu.listener.UserListener</listener-class>

 </listener>

在线人数统计程序存在一些问题,如果用户没有退出登录而直接关闭了浏览器,那么在服务器端的Session中,这个用户仍然是存在的,直到Session的超时值发生。所以在线人数统计只能做到在一个时间段内统计出大致的在线人数,而不能统计出精确的人数。为了提高统计的精确性,可以在客户端设置脚本,当浏览器关闭时,自动向服务器发送一个请求,服务器收到这个请求后,使Session失效。不过,这也不能做到100%的精确,因为还存在着客户端的浏览器异常终止,或者客户机器崩溃的可能。

转载自—————-http://blog.sina.com.cn/s/blog_6e5988eb01013iva.html

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注