陈慧琳合成图,啸天者欧穆隆,不死恋人
本文主要介绍了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<sessionanduser> sessions; static int dels = -1; static boolean flag = false; static { if (sessions == null) { sessions = collections .synchronizedlist(new arraylist<sessionanduser>()); } } 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<sessionanduser>存放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"; }
页面捕获提示信息代码
<%@taglib prefix="s" uri="/struts-tags"%> <s:property value="#attr.timeoutmsg" />
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
apollo与springboot集成实现动态刷新配置的教程详解
网友评论