java中使用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。这是我感觉不清楚的地方,功夫没到家。
具体实现:
监听器代码
publicclassOnlineListenerimplementsHttpSessionListener, HttpSessionAttributeListener{ privatestaticList<SessionAndUser>sessions; staticintdelS=-1; staticbooleanflag=false; static{ if(sessions==null){ sessions=Collections .synchronizedList(newArrayList<SessionAndUser>()); } } publicvoidsessionCreated(HttpSessionEventhse){ System.out.println(hse.getSession()+"-"+newDate()); System.out.println(hse.getSession()+"-"+newDate()); } publicvoidsessionDestroyed(HttpSessionEventhse){ System.out.println("-------------sessionDestroyed()-----------"); System.out.println(hse.getSession()+"" +newDate(hse.getSession().getLastAccessedTime())); System.out.println(hse.getSession()+""+newDate()); } publicvoidattributeAdded(HttpSessionBindingEvente){ System.out.println("-------------*startadded*-----------------------" +sessions.size()); HttpSessionsession=e.getSession(); ActionContextctx=ActionContext.getContext(); booleannewOne=true; StringattrName=e.getName(); //登录 if(attrName.equals(Constant.USER_NAME)){ //检查登录人数 if(sessions.size()>=Constant.USER_LIMIT){ newOne=false; ctx.put("timeoutMSG","serverBusy"); } StringnowUser=(String)e.getValue(); //遍历所有session,检查是否已经登录,若是则提示已经登录 for(inti=sessions.size()-1;i>=0;i--){ SessionAndUsertem=sessions.get(i); if(tem.getUserName().equals(nowUser)){ newOne=false; ctx.put("timeoutMSG","beenLoged");//tem.getSession().invalidate();// //同账号顶替登录,自动调用remove break; } } //新登录帐号添加进账户维护列表 if(newOne){ SessionAndUsersau=newSessionAndUser(); sau.setUserName(nowUser); sau.setSession(session); sau.setSid(session.getId()); sessions.add(sau); } } } publicvoidattributeRemoved(HttpSessionBindingEvente) throwsIllegalStateException{ HttpSessionsession=e.getSession(); System.out .println("-------------*startRemoved*-----------------------" +sessions.size()); if(delS>-1){ if(flag){ sessions.remove(delS); flag=false; } }else{ //登录 StringattrName=e.getName(); if(attrName.equals(Constant.USER_NAME)){ StringnowUser=(String)e.getValue(); //遍历所有session for(inti=sessions.size()-1;i>=0;i--){ SessionAndUsertem=sessions.get(i); if(tem.getUserName().equals(nowUser)){ sessions.remove(i); break; } } } } } publicvoidattributeReplaced(HttpSessionBindingEvente){ HttpSessionsession=e.getSession(); System.out .println("-------------*startreplace*-----------------------" +sessions.size()); StringattrName=e.getName(); delS=-1; //登录 if(attrName.equals(Constant.USER_NAME)){ //UsernowUser=(User)e.getValue();//oldvalue StringnowUser=(String)session.getAttribute(Constant.USER_NAME);//当前session中的user //遍历所有session for(inti=sessions.size()-1;i>=0;i--){ SessionAndUsertem=sessions.get(i); if(tem.getUserName().equals(nowUser) &&!tem.getSid().equals(session.getId())){ System.out.println("Remove:invalidate1!"); delS=i; flag=true; }elseif(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()); ActionContextctx=ActionContext.getContext(); if("serverBusy".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG","服务器繁忙,请稍后再试"); return"jump"; } if("beenLoged".equals(ctx.get("timeoutMSG"))){ ctx.put("timeoutMSG","此账户在别处登录"); return"jump"; }
页面捕获提示信息代码
<%@taglibprefix="s"uri="/struts-tags"%> <s:propertyvalue="#attr.timeoutMSG"/>
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!