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

写一个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失效时,也是会触发属性移除时间的.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zerlinda_Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值