In java session is used to realize the same account logon limit and the number of logins

  • 2020-05-10 18:15:19
  • OfStack

This paper mainly introduces the use of session in java to realize the same account logon limit and the number of logon limits. The specific codes are as follows:

The problem domain:

1. Login with the same account: if the account is already logged in, it cannot be logged in again (contrary to QQ mode).

2. Limit of the number of logins. If the number exceeds or has reached the limit, the system is busy, please try again later.

Solution: use HttpSessionAttributeListener listener (although I used HttpSessionListener at the same time, it was not easy to operate)

Knowledge reserve: HttpSessionAttributeListener has three methods: attributeAdd, attributeRemove and attributeReplace.

The setAttribute and removeAttribute of session will trigger the attributeAdd and attributeRemove methods, and the same session of session will trigger the attributeReplace method.

The reason why HttpSessionListener is not easy to operate is that if you visit the jsp page, session will be created (visiting html does not create session, but HttpServletRequest.getSession (true) will be created when you call HttpServletRequest.getSession (true) in servlet). jsp is a dynamic page, which is essentially an servlet. My login.jsp is obviously an jsp, and when I invalidate1 session in the listener, go back to the login page, I immediately create another session. This is where I don't feel clear, kung fu is not home.

Specific implementation:

Listener code


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();
    //  The login 
    if (attrName.equals(Constant.USER_NAME)) {
      //  Check number of logins 
      if (sessions.size() >= Constant.USER_LIMIT) {
        newOne = false;
        ctx.put("timeoutMSG", "serverBusy");
      }
      String nowUser = (String) e.getValue();
      //  Iterate over all session , check whether you have logged in. If so, you will be prompted to log in 
      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();//
                            //  Replace login with the same account, automatic call remove
          break;
        }
      }
      //  New login account added to account maintenance list 
      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 {
      //  The login 
      String attrName = e.getName();
      if (attrName.equals(Constant.USER_NAME)) {
        String nowUser = (String) e.getValue();
        //  Iterate over all 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;
    //  The login 
    if (attrName.equals(Constant.USER_NAME)) {
      // User nowUser = (User) e.getValue();//old value
      String nowUser = (String) session.getAttribute(Constant.USER_NAME);//  The current session In the user
      //  Iterate over all 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();//  It was called automatically when it failed remove Methods. I'm going to take it from sessions removed 
      }
    }
  }
}

The main idea of the code is to define a static List < SessionAndUser > Store session and account name.

The code that gets the listener return value and processes it in the login Action


session.setAttribute(Constant.USER_NAME, operator.getUsername());
    ActionContext ctx = ActionContext.getContext();
    if("serverBusy".equals(ctx.get("timeoutMSG"))){
      ctx.put("timeoutMSG", " The server is busy, please try again later ");
      return "jump";
    }
    if("beenLoged".equals(ctx.get("timeoutMSG"))){
      ctx.put("timeoutMSG", " This account is logged in elsewhere ");
      return "jump";
    }

The page captures the prompt code


<%@taglib prefix="s" uri="/struts-tags"%>
<s:property value="#attr.timeoutMSG" />

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: