问题背景:
试想,如果同时有两个用户使用一个账号登录系统,
他们两个人需要对一批文章进行编辑。
都已经把同一篇文章读取到了浏览器中各自进行编辑后提交,
那么就会出现该文章只会保存一个人提交的结果。
先提交的那个人的将会被覆盖掉。
核心思想:
背景:由于每次请求的 sessionId 都不一样。
确保:每个用户名只能对应一个 session
方法:
在全局变量中维护一个 session 列表。
如果相同的用户名,出现不一样的 sessionId,
说明该用户进行了第二次登录,
则使原来存在的 session 失效(移除 session )。
页面可以加轮询次数(时间)控制,
无需等到用户下一次手动提交请求。
1、第一次登陆成功
String userIdDecode = "登陆名"; ServletContext context=null; context = this.getSession().getServletContext(); HttpSession session = this.getSession(); Map<String,HttpSession> usersMap = (Map<String, HttpSession>) context.getAttribute("usersMap"); //第一个用户登录时 if(usersMap == null){ usersMap = new HashMap<String,HttpSession>(); usersMap.put(userIdDecode, session); context.setAttribute("usersMap", usersMap); //将用户保存到ServletContext对象中 //非第一个用户登录 }else{ if(usersMap.containsKey(userIdDecode)){ logger.info("第二次登陆,remove掉"+userIdDecode); usersMap.remove(userIdDecode); } logger.info("添加当前用户到map"+userIdDecode); usersMap.put(userIdDecode, session); } this.setSessionValue("user", userIdDecode);
说明:
这里不用把整个session放到全局变量中,
可以只放一个 seesionId 即可。
2、拦截器拦截每一个请求路径,判断用户是否已经在别处登录
//获取用户信息 HttpSession session = this.getSession(); String user = (String)session.getAttribute("user"); System.out.println("当前登陆用户:"+user+"当前用户的sessionId"+session.getId()); Map<String,HttpSession> usersMap = (Map<String, HttpSession>) session.getServletContext().getAttribute("users"); if(null != usersMap){ if(null == user){ result = ""; return null; } if(usersMap.containsKey(user)){ if(session.getId().equals(usersMap.get(user).getId())) result = "true"; else result = "false"; }else { if(null==usersMap.get(user)) result = "true"; else result = "false"; } }else{ result = ""; } try { ServletActionContext.getResponse().getWriter().print(result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
3、前台ajax轮询用户当前状态
//如果是在首页结束轮询 var countTimeOut = 0; //轮询当前用户 var t2 = window.setInterval("loadXMLDoc()",1000); function loadXMLDoc() { countTimeOut = countTimeOut+1; if(countTimeOut == 1800){ $.ajax({ type:"post", url:"cleanSession", dataType : "text", error:function(){ window.location.href="http://toIndex.action"; } }); } $.ajax({ type:"post", url:"sessionLive", dataType : "text", success:function(data){check(data)}, error:function(){ window.location.href="http://toIndex.action"; } }); } function check(result){ if(result=="true"){ }else{ if(result=="false"){ alert("您已经在别处登陆"); $.ajax({ type:"post", url:"cleanSession", dataType : "text", error:function(){ window.location.href="http://toIndex.action"; } }); window.location.href="http://toIndex.action"; }else{ clearInterval(t2); } } } //轮询当前用户结束
4、清除当前session信息
//获取用户信息 String user = (String)this.getSession().getAttribute("user"); Map<String,HttpSession> usersMap = new HashMap<String, HttpSession>(); HttpSession session = this.getSession(); usersMap = (Map<String, HttpSession>)session.getServletContext().getAttribute("users"); if(null != usersMap){ if(usersMap.containsKey(user)){ if(session.getId().equals(usersMap.get(user).getId())) { usersMap.remove(user); } }} this.getSession().invalidate();
5、监听器
application = event.getSession().getServletContext(); Map<String,HttpSession> usersMap = new HashMap<String, HttpSession>(); HttpSession session = event.getSession(); String user = (String)session.getAttribute("user"); usersMap = (Map<String, HttpSession>)application.getAttribute("users"); if(null != usersMap){ if(usersMap.containsKey(user)){ if(session.getId().equals(usersMap.get(user).getId())){ usersMap.remove(user); } } } //将session设置成无效 event.getSession().invalidate(); System.out.println("一个Session被销毁了!"+user);
-