微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java中使用session监听实现同帐号登录限制、登录人数限制

本文主要介绍了java中使用session监听实现同帐号登录限制、登录人数限制,通过session来监听在线人数和登陆限制,有需要的童鞋可以了解一下。

本文主要介绍了java中使用session监听实现同帐号登录限制、登录人数限制,具体代码如下:

问题域:

1、同帐号登录:若此帐号已登录,不可再次登录(与QQ模式相反)。

2、登录人数限制,超过、已达人数限制则提示:系统繁忙,稍后再试。

解决思路:使用HttpSessionAttributeListener监听器(虽然我同时使用了HttpSessionListener不过感觉不好操作)

知识储备:HttpSessionAttributeListener中有attributeAdd、attributeRemove、attributeReplace3个方法

对session的setAttribute、removeAttribute将触发attributeAdd、attributeRemove方法,对同一个session的同一个attribute进行重复设置将触发attributeReplace方法

HttpSessionListener不好操作的原因:只要访问jsp页面便会创建session(访问html并不会创建session,在server端,如servlet中调用HttpServletRequest.getSession(true)才会创建),jsp是动态页,本质就是个servlet。我的login.jsp显然是个jsp,当我在监听器中invalidate一个session,返回登录页,马上就又创建了一个session。这是我感觉不清楚的地方,功夫没到家。

具体实现:

监听器代码

public class OnlineListener implements HttpSessionListener, HttpSessionAttributeListener { private static List sessions; static int delS = -1; static boolean flag = false; static { if (sessions == null) { sessions = Collections .synchronizedList(new ArrayList()); } } public void sessionCreated(HttpSessionEvent hse) { System.out.println(hse.getSession() + "-" + new Date()); System.out.println(hse.getSession() + "-" + new Date()); } public void sessionDestroyed(HttpSessionEvent hse) { System.out.println("-------------sessionDestroyed()-----------"); System.out.println(hse.getSession() + " " + new Date(hse.getSession().getLastAccessedTime())); System.out.println(hse.getSession() + " " + new Date()); } public void attributeAdded(HttpSessionBindingEvent e) { System.out.println("-------------*start added*-----------------------" + sessions.size()); HttpSession session = e.getSession(); ActionContext ctx = ActionContext.getContext(); boolean newOne = true; String attrName = e.getName(); // 登录 if (attrName.equals(Constant.USER_NAME)) { // 检查登录人数 if (sessions.size() >= Constant.USER_LIMIT) { newOne = false; ctx.put("timeoutMSG", "serverBusy"); } String NowUser = (String) e.getValue(); // 遍历所有session,检查是否已经登录,若是则提示已经登录 for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(NowUser)) { newOne = false; ctx.put("timeoutMSG", "beenLoged");// tem.getSession().invalidate();// // 同账号顶替登录自动调用remove break; } } // 新登录帐号添加进账户维护列表 if (newOne) { SessionAndUser sau = new SessionAndUser(); sau.setUserName(NowUser); sau.setSession(session); sau.setSid(session.getId()); sessions.add(sau); } } } public void attributeRemoved(HttpSessionBindingEvent e) throws IllegalStateException { HttpSession session = e.getSession(); System.out .println("-------------*start Removed*-----------------------" + sessions.size()); if (delS > -1) { if (flag) { sessions.remove(delS); flag = false; } } else { // 登录 String attrName = e.getName(); if (attrName.equals(Constant.USER_NAME)) { String NowUser = (String) e.getValue(); // 遍历所有session for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(NowUser)) { sessions.remove(i); break; } } } } } public void attributeReplaced(HttpSessionBindingEvent e) { HttpSession session = e.getSession(); System.out .println("-------------*start replace*-----------------------" + sessions.size()); String attrName = e.getName(); delS = -1; // 登录 if (attrName.equals(Constant.USER_NAME)) { // User NowUser = (User) e.getValue();//old value String NowUser = (String) session.getAttribute(Constant.USER_NAME);// 当前session中的user // 遍历所有session for (int i = sessions.size() - 1; i >= 0; i--) { SessionAndUser tem = sessions.get(i); if (tem.getUserName().equals(NowUser) && !tem.getSid().equals(session.getId())) { System.out.println("Remove:invalidate 1!"); delS = i; flag = true; } else if (tem.getSid().equals(session.getId())) { tem.setUserName(NowUser); } } if (delS != -1) { sessions.get(delS).getSession().invalidate();// 失效时自动调用了remove方法。也就会把它从sessions中移除了 } } } }

代码主要思路是定义一个静态List存放session和帐号名称

登录的Action中获得监听器返回值并处理的代码

session.setAttribute(Constant.USER_NAME, operator.getUsername()); ActionContext ctx = ActionContext.getContext(); if("serverBusy".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "服务器繁忙,请稍后再试"); return "jump"; } if("beenLoged".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG", "此账户在别处登录"); return "jump"; }

页面捕获提示信息代码

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐