首页 > 编程 > Java > 正文

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

2019-11-26 13:41:05
字体:
来源:转载
供稿:网友

本文主要介绍了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" />

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表