Session management timeout setting and forced offline

    Regarding Session, in Java Web development, it provides us with a lot of convenience. Session is maintained between the browser and the server. Well, without further ado, let's implement them step by step.

    (1) First of all, let’s talk about the three ways to set the session timeout time. These are relatively simple:

    (1) Set session-config in web.xml

<session-config>
  <session-timeout>2</session-timeout>
 </session-config>

    That is, the maximum interaction interval is 2 minutes (the time unit here is minutes), and the value obtained by session.getAttribute() after 2 minutes is empty.

    (2) session-config in Tomcat's /conf/web.xml, the default value is: 30 minutes

<session-config>
     <session-timeout>30</session-timeout>
</session-config>

    Same as above, the time unit is minutes.

    (3) Set in Servlet

HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);

    That is, set it manually in your program code (the time unit here is seconds).

    Priority: Servlet settings > web.xml settings > Tomcat/conf/web.xml settings

    (2) Forced offline for the same user

    We all know that in many current web projects, in most cases, the same user account can be logged in at different login portals, but this is actually not very rigorous. After all, operations such as information modification can affect the information Full real-time synchronization is still unknown. So, next, what I want to do is to force the offline processing of the same user account of different browsers. I will not consider the same browser for the time being. Let’s first look at the following picture. Get a rough idea of:

    It can be seen from the above that the same browser will generate the same sessionId when logging in for different accounts, which also leads to the coverage of information between users; when different browsers log in to different accounts, the login will be different. The sessionId, which also gives us operational space, it is to use this point to judge and deal with it accordingly.

    (1) Add a listener

    In order to facilitate the use of Session monitoring here, create a SessionListener as follows:

public class SessionListener implements HttpSessionBindingListener{

    @Override
    public void valueBound(HttpSessionBindingEvent event){
        // TODO Auto-generated method stub
        
    }
    @Override
    public void valueUnbound(HttpSessionBindingEvent event){
        // TODO Auto-generated method stub
        
    }
}

    Here HttpSessionBindingListener and HttpSessionListener have the same effect, you can choose one of them. Overload two methods: session creation and destruction.

    Of course, it is essential to add the corresponding configuration in web.xml:

<listener>
   <listener-class>com.yoki.util.SessionListener</listener-class>
</listener>

    Since sessionId and userId need to be stored for later judgment, we add two Maps to the above class, as follows:

//保存username和session的映射
public static HashMap<String,Session> MAP1 = new HashMap<String,Session>();
//保存sessionID和username的映射
public static HashMap MAP2 = new HashMap();

    Finally, when the user's login verification is successful, a method needs to be called to determine whether to force the offline:

public static void userLogin(Session session,String sUserName){
    //已登录
    if(MAP2.containsValue(sUserName)){
       Session l_session = MAP1.get(sUserName);
       //不同浏览器,同一用户(强制下线前一个)
       if(l_session != null && l_session.getId() != session.getId()){
          MAP1.remove(sUserName);
          MAP2.remove(l_session.getId());
          l_session.setAttribute("msg", "您的账号已在另一处登录!");
          MAP2.put(session.getId(), sUserName);
          MAP1.put(sUserName, session);
       }
       //同一浏览器,同一用户(不做任何变动)
       
    }else{
       //未登录
       if(MAP2.containsKey(session.getId())){
          //同一浏览器,不同用户(不做任何变动)
       }else{
          //不同浏览器,不同用户(正常添加)
          MAP2.put(session.getId(), sUserName);
          MAP1.put(sUserName, session);
       }
    }

}

    Explain: the effect of using username and userId is the same here. It depends on how convenient you use it. The logic in the method is written according to the above diagram. First, determine whether the user is logged in, because the relevant session association information is saved in the MAP. Therefore, it can be judged by this; since only the same users of different browsers are processed here, it is directly judged whether it is the same browser. The parameter session of the method is the information of the user when the user logs in the current browser. We can get the session information of the same user saved before from the MAP, and compare with it. The logic inside is: remove the previous user saved in the MAP. information (the corresponding session is not destroyed at this time), and add a msg information to its session (used later, look down), and then add new user information.

    The above method calls are placed after the login verification is successful, and their projects are different, but the login verification classes are basically the same:

SessionListener.userLogin(session, USERNAME);

    (2) Add the method called by the front-end page

    Add the following method to the login authentication class:

/*
 * 判断用户是否重复登录
 */
@RequestMapping(value="/checkUserOnline")
@ResponseBody
public void checkUserOnline(HttpServletRequest request,HttpServletResponse response) throws IOException{
    HttpSession session=request.getSession();  
    PrintWriter out = response.getWriter();
    String msg = "";
    if(session.getAttribute("msg") != null){
       msg = session.getAttribute("msg").toString();
       System.out.println(msg);
    }
    out.print(session.getAttribute("msg"));
}

    In the method, the msg previously added to the session is obtained, which is used to judge whether to force the offline and continue.

    (3) Front-end page loop call

    Select a page, preferably used by all pages, such as the index.jsp I use, as follows:

<script type="text/javascript">
   $(document).ready(function(){
      setInterval("checkUserOnline()",5000); //每隔5秒判断一次
   }
   
   function checkUserOnline(){
      var msg = "";
      $.ajax({
        type : "POST",
        url : "checkUserOnline",
        data : {},
        async: false,
        success : function(data){
           msg = data;
        }
      });
      if (msg == 'null' || msg == '' || msg == 'undefined'){
         return;
      }else{
         //调用你的注销用户方法
         var url="<%=path%>/logout.do";
         $.get(url,function(data){});
      }
   }
</script>

    Call the setInterval method in js to set the calling method and interval time. In the method, the class added above is called through ajax and returns msg, and msg is used to judge whether to call the logout method (note the path, if you can call it, it is ok).

    (4) Cancellation

    Generally, a web project will have an exit button after logging in. Click it to return to the login page. At this time, add a line of code in it to prevent errors. There may be an error message indicating that the session has been destroyed after logging in again, but the second time it will be Success, here is to get rid of the error:

SessionListener.MAP2.remove(session.getId());

    Ok, the basic settings are completed, start the project, open two different browsers, log in to one user first, after success, log in the same user in another browser, after the login is successful, it will print out on the console msg:

您的账号已在另一处登录!

    At this point, refresh the first browser user login interface, and you will find that you have exited and jumped to the login page, and you're done! ! !

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324398414&siteId=291194637