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);
        }
    }

    //写一个判断用户是否已经登陆的方法
    public boolean isLogonUser(Long userId) {
        Set<HttpSession> keys = SessionListener.loginUser.keySet();
        for (HttpSession key : keys) {
            if (SessionListener.loginUser.get(key).equals(userId)) {
                return true;
            }
        }
        return false;
    }

}

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

    <listener>
        <listener-class>监听器(类)的完全限定名</listener-class>
    </listener>

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

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

Map<String, HttpSession> loginUser = SessionListener.loginUser;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值