实现限制用户在不同地点重复登录账号

    有些情况下你也许会由这样的一个需求,就是限制同一个账号在不同地点上面重复登录,就像QQ一样,一个账号只能一个人登录,别人登录你的账号的话,那你这边就会提示“已在别处登录”并强制登出。
    其实实现起来不是很麻烦,在这里给出我自己的做法,如果有更好地方法可以在这里跟大家分享一下。
    在用户登录的时候把用户放在Session中的同时,在ServletContext也维护这一个Map<用户名,SessionID>(也可以用DB来实现),在该Map里面也同时添加一条记录;实现一个Filter(或这是用拦截器)来对用户进行访问验证,如果第二个人在另外一个地点是用同一个用户名登录的话,那么Map中用户名所对应的Value就会发生变化,当以一个人再对资源进行访问的话,那么到Filter那关发现,用户名所对应的SessionID已经改变了,那么就提示第一个用户这个用户名已在别处登录。
    清理ServletContext维护的Map的做法,在用户登录的时候,把一个实现HttpSessionBindingListener的监听器Set进去,HttpSessionBindingListener接口中有两个方法valueBound和valueUnbound,在valueBound方法中实现的是对Map属性的添加记录,在valueUnbound方法里面实现的是对Map里面的属性进行删除操作;在用户登出操作的时候可以销毁Session。
//在把该类的对象set进session的时候,会自动调用
public void valueBound(HttpSessionBindingEvent event){
    HttpSession session = event.getSession();
    ServletContext application = session.getServletContext();
    //判断维护的Map是否存在,不存在就new
    //...
    Map<String, String> userList = ...;
    userList.put(session.getAttribute("USER_KEY",session.getId()));
}

//该方法被调用的情况:
//手动调用invalidate方法时回调
//session过期时回调
//session.removeAttribute()时回调
//session.setAttribute("set进去的key","其他对象")
public void valueUnbound(HttpSessionBindingEvent event){
    //取出ServletContext的Map
    //取出Map中当前用户多对应的sessionId,判断当前Session的ID和Map中的SessionId是否一致,true代表该用户正常退出,false代表强制退出
    //正常退出直接remove掉Map对应的值,否则什么事情都不做。
}

猜你喜欢

转载自sch.iteye.com/blog/1325069