其实实现起来不是很麻烦,在这里给出我自己的做法,如果有更好地方法可以在这里跟大家分享一下。
在用户登录的时候把用户放在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对应的值,否则什么事情都不做。 }