入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

统计在线用户数以及同账号登录踢出另一用户

创建时间:2016-06-03 投稿人: 浏览次数:86

写一个session属性监听器:定义两个map,一个存session,以用户编号为key;一个存用户信息,也以用户编号为key.map的个数就是在线用户数.每个用户登录时,先检查map中是否存在,如果不存在,就新增到map里面去,如果存在,就通过用户编号找对应session使其失效.再将当前登录用户信息写入到map里面.

package com.sunshine.monitor.comm.filter;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

import com.sunshine.monitor.system.manager.bean.SysUser;

/**
 * session属性监听,用于统计在线用户数,同一账户登录踢出在线用户
 * 对于直接关闭浏览器的操作等待session失效之后,才能做到清除.
 * @date 2016-6-1
 * @author licheng 
 *
 */
public class SessionListener implements HttpSessionAttributeListener{

	/**
	 * 定义监听的session属性名
	 */
	public final static String LISTENER_NAME = "_login";	
	public final static String LISTENER_COUNT = "_count";
	
	/**
	 * 定义存储客户登录用户的集合
	 */
	private static Map<String, SysUser> users = new HashMap<String, SysUser>();
	
	/**
	 * 定义存储客户登录session的集合
	 */
	private static Map<String, HttpSession> sessions = new HashMap<String, HttpSession>();
	
	/**
	 * 定义存储在线用户数的集合
	 */
	private static Map<String, Integer> counts = new HashMap<String, Integer>();
	
	/**
	 * 加入session时的监听方法
	 * 
	 * @param HttpSessionBindingEvent
	 * 				session事件
	 */
	public void attributeAdded(HttpSessionBindingEvent sbe) {
		if(LISTENER_NAME.equals(sbe.getName())){
			SysUser s = (SysUser) sbe.getValue();
			if(users.containsKey(s.getYhdh())) {
				HttpSession session = sessions.get(s.getYhdh());
				session.removeAttribute(LISTENER_NAME);
				session.invalidate();
			} 
			sessions.put(s.getYhdh(), sbe.getSession());
			users.put(s.getYhdh(), s);
		}
		Integer count = users.size();
		counts.put(LISTENER_COUNT, count);
	}
	
	/**
	 * session失效时的监听方法
	 * 
	 * @param HttpSessionBindingEvent
	 * 				session事件
	 */
	public void attributeRemoved(HttpSessionBindingEvent sbe) {
		if(LISTENER_NAME.equals(sbe.getName())){
			// 从session集合中减去一个
			SysUser s = (SysUser) sbe.getValue();
			sessions.remove(s.getYhdh());
			users.remove(s.getYhdh());
			counts.put(LISTENER_COUNT, users.size());
		}
	}
	
	/**
	 * session覆盖时的监听方法
	 * 
	 * @param HttpSessionBindingEvent
	 * 				session事件
	 */
	public void attributeReplaced(HttpSessionBindingEvent sbe) {
		
	}
	
	public static Map<String, SysUser> getUsers() {
		return users;
	}
	
	public static Map<String, HttpSession> getSessions() {
		return sessions;
	}
	
	public static Map<String, Integer> getCounts() {
		return counts;
	}
	
}

监听器写好之后要在web.xml里面配置一下.
  <listener>
    <listener-class>com.sunshine.monitor.comm.filter.SessionListener</listener-class>
  </listener>

如何使用呢,用户登录时给session设置一个数据,获取在线用户数

		request.getSession().setAttribute(SessionListener.LISTENER_NAME, s);
		application.setAttribute("online", SessionListener.getCounts().get(SessionListener.LISTENER_COUNT));

页面上的在线人数这样获取:

<c:out value="${online}"></c:out>

注销时,这样写:

	/**
	 * 注销移除sesson,从设置application的onlines属性
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping
	public ModelAndView logout(HttpServletRequest request,
			HttpServletResponse response){
		ModelAndView mv = new ModelAndView(forwardLoginPath);
		HttpSession session = request.getSession();
		session.removeAttribute(SessionListener.LISTENER_NAME);
		session.invalidate();
		session.getServletContext().setAttribute("online", SessionListener.getCounts().get(SessionListener.LISTENER_COUNT));
		return mv;
	}

如果用户非法退出,如直接关闭浏览器,关闭窗口等.这时session并不会立即失效.我尝试过使用js监听窗口关闭操作,然后移除session.可是这段js只适用于ie8及以下.最终放弃,只能等待session失效.session的失效时常是在web.xml里面设置的.

session失效时,也是会触发属性移除时间的.


声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
  • 上一篇:没有了
  • 下一篇:没有了
未上传头像