session监听防止用户登录重复


思路,主要是实现一些session监听器的接口,在session中set属性时,判断是不是user对象,然后缓存下来,userName为key,session对象为value,

然后,每次登录的时候去这个缓存中查找是否有这个用户,取出来的session为空则没有,取出来有值,则改用户已登录过了,

后面就是自己的逻辑了。

有2种

------------------------------------

1,后登陆的挤掉先登录的,就是把查出来的老的session关闭掉,然后把用户保存到session,内部把现在的用户和其对应的session作为键值对都缓存起来。

2,后登陆的登不上,先登录的一直保持,这个就是登录时查找缓存的用户集合,如果已经有这个用户了,就不让他登录。。


然后要做的就是,session关闭,失效,超时,浏览器关闭(web程序),用户退出等时候要去把缓存的中对应的user-session键值对清除,不然,如果采用第二种方案的话就可能造成用户登不上,因为缓存中还有这个用户。


在这个基础上要实现踢人或者统计在线用户就很简单了,直接取缓存用户的map的长度,或者从缓存用户的map中查找出session,让session失效。。




1,监听器类

package cn.hydom.ztc.ztc_app.controller.listener;

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

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.hydom.ztc.ztc_dao.entity.User;

/**
 * @Description: session监听器 用户唯一登录,后登陆挤掉先登录的
 * @author whl
 * @date 2014-10-21
 */

public class SessionListener implements HttpSessionListener,
		HttpSessionAttributeListener {

	// log4j
	private final static Log log = LogFactory.getLog(SessionListener.class);

	// 保存当前登录的所有用户
	public static Map<String, HttpSession> loginUser = new HashMap<String, HttpSession>();

	// 用这个作为session中的key
	public static String SESSION_LOGIN_NAME = "user";

	// 执行setAttribute的时候, 当这个属性本来不存在于Session中时, 调用这个方法.
	@Override
	public void attributeAdded(HttpSessionBindingEvent se) {

		// 如果添加的属性是用户名, 则加入map中
		if (se.getName().equals(SESSION_LOGIN_NAME)) {

			User u = (User) se.getValue();
			HttpSession session = loginUser.remove(u.getUserName());
			if (session != null) {
				session.removeAttribute("user");
			}
			loginUser.put(u.getUserName(), se.getSession());
		}

	}

	// 当执行removeAttribute时调用的方法
	@Override
	public void attributeRemoved(HttpSessionBindingEvent se) {
		// 如果移除的属性是用户名, 则从map中移除
		if (se.getName().equals(SESSION_LOGIN_NAME)) {
			try {
				User u = (User) se.getSession().getAttribute("user");
				loginUser.remove(u.getUserName());
			} catch (Exception e) {
				log.debug(e);
			}
		}
	}

	// 当执行setAttribute时 ,如果这个属性已经存在, 覆盖属性的时候, 调用这个方法
	@Override
	public void attributeReplaced(HttpSessionBindingEvent se) {
		// 如果改变的属性是用户名, 则跟着改变map
		if (se.getName().equals(SESSION_LOGIN_NAME)) {

			User u = (User) se.getValue();
			HttpSession session = loginUser.remove(u.getUserName());
			/*if (session != null) {
				session.removeAttribute("user");
			}*/
			loginUser.put(u.getUserName(), se.getSession());
		}
	}

	// session创建时调用这个方法
	@Override
	public void sessionCreated(HttpSessionEvent se) {
		log.debug("SessionListener........session创建-----"
				+ se.getSession().getId());
	}

	// Session失效或者过期的时候调用的这个方法,
	@Override
	public void sessionDestroyed(HttpSessionEvent se) {
		// 如果session超时, 则从map中移除这个用户
		try {
			User u = (User) se.getSession().getAttribute("user");
			loginUser.remove(u.getUserName());
		} catch (Exception e) {
			log.debug(e);
		}
	}

}


2,web.xml中配置监听器类

<!-- session监听器 监听用户登录 -->
	<listener>
		<listener-class>cn.hydom.ztc.ztc_app.controller.listener.SessionListener</listener-class>
	</listener>

3,用户登录时的逻辑判断

//根据用户名查找,判断是否为空,实现自己的逻辑,挤掉还是不允许登录

Map<String, HttpSession> loginUser = SessionListener.loginUser;




评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值