android keep session

android keep session

Complete the function of realizing app online user list on the server side, whether it is HttpSessionListener or HttpSessionBindingListener all rely on session mechanism. However, before the app exits, the session session on the server side is destroyed, resulting in the inability to properly monitor the online status of the app user.

1. The life cycle of the session

  • When the server receives the request, the server will assign asession会话

  • This session会话has a maximum save time MaxInactiveInterval, when the user 不活动状态exceeds this time, the session will be destroyed

  • If it is a web page, the session will be destroyed when the user logs out or exits the browser

2. The reason why android cannot maintain the session

  • Each request on the web page is active, and the reset session会话time will be implemented to achieve persistent access

  • The Android side is different. The sessionId is not included in its request header, so the server cannot identify which session it is accessing, nor which session the request came from

3. Solve the problem

It is recommended that you install FireFox browser, its check function is really easy to use, better than Google Chrome

  • Write a servlet, run the server, add a css link to the web page

  • Open the webpage with FireFox and check

  • Note that the highlighted Cookie:JSESSIONID=70943E03B9683A966235579F4D57892F, printed session.getId()verification, found that this JSESSIONIDis the sessionsessionId

  • How to check the request header of android access server? Add the following code in the servlet:

    	Cookie[] Cookies = request.getCookies();
    	for(int i =0;i<Cookies.length;i++){
    		Cookie c = Cookies[i];
    		System.out.println(c.getName() + "=" + c.getValue());
    	}
    
  • Use android to initiate a request and report an error java.lang.NullPointerException, indicating that android's default request is without cookies

  • Add Cookie to the request header of android, I use OkHttp3 here

    Request request = new Request.Builder()
                    .url(url).addHeader("Cookie", "JSESSIONID=" + session_id)
                    .post(body)
                    .build();
    
  • As for this session_id, you can do this: the server receives the login request, obtains the sessionID of the session, and returns it to the android side.

  • Use the method with cookies to access the server again, you can see the print out JSESSIONID, at this time android and the web can achieve session persistence

4. Verify Session Persistence

  • Add in the web.xml of the server project

    <session-config>
    	<session-timeout>1</session-timeout>
    </session-config>
    
  • Indicates that the maximum session save time is set to 1 minute, set to 1 minute is to facilitate verification

  • Add an online user listener, here is a plan:

    //登录处理的Servlet添加,user为用户实体对象
    session.setAttribute("onlineUserBindingListener", new OnlineUserBindingListener(user));
    
    //在线用户监听器,使用注解方式
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.ServletContext;
    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionBindingListener;
    
    import domain.User;
    
    @WebListener
    public class OnlineUserBindingListener implements HttpSessionBindingListener {
    
    	private User user;
    
    	public OnlineUserBindingListener() {
    
    	}
    
    	public OnlineUserBindingListener(User user) {
    		this.user = user;
    	}
    
    	@SuppressWarnings("unchecked")
    	public void valueBound(HttpSessionBindingEvent event) {
    		HttpSession session = event.getSession();
    		ServletContext application = session.getServletContext();
    
    		List<User> onlineUserList = (List<User>) application.getAttribute("onlineUserList");
    
    		if (onlineUserList == null) {
    			onlineUserList = new ArrayList<User>();
    			application.setAttribute("onlineUserList", onlineUserList);
    		}
    		onlineUserList.add(this.user);
    	}
    
    	@SuppressWarnings("unchecked")
    	public void valueUnbound(HttpSessionBindingEvent event) {
    		HttpSession session = event.getSession();
    		ServletContext application = session.getServletContext();
    
    		List<User> onlineUserList = (List<User>) 			           application.getAttribute("onlineUserList");
    
    		onlineUserList.remove(this.user);
    	}
    }
    
  • The web page displays the user list, directly application.getAttribute ("onlineUserList"), I will not repeat them. The web page refreshes automatically every 30 seconds:

    <meta http-equiv="refresh" content="30"/>
    
  • App does not operate after login, the user list data disappears after 1 minute

  • The app operates continuously after logging in. Each operation interval is within 1 minute, and the user list data continues to exist. Successful verification

5. Other

  • The getAttribute and setAttribute methods of the session will not affect its life cycle , and are still regarded as inactive

  • The method of obtaining session based on sessionId has been deprecated after Servlet 2.5. If you still want to implement this function, please refer to https://blog.csdn.net/sihai12345/article/details/81098765HashMap<String,HttpSession>

  • The list of entity types displayed in Jsp is combined with JSTL and EL expressions as much as possible. It is simple and clear. Don't forget to use JSTL to guide the package. Examples:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<c:when test="${requestScope.operat_type eq 'userList'}">
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>密码</th>
                <th>部门</th>
                <th>等级</th>
                <th>注册时间</th>
                <th>最近登录时间</th>
                <th>最近登录IP</th>
                <th>登录次数</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${requestScope.userList}" var="user">
                <tr>
                    <td>${user.name }</td>
                    <td>${user.password }</td>
                    <td>${user.department }</td>
                    <td>${user.grade }</td>
                    <td>${fn:substring(user.reg_time,0,19) }</td>
                    <td>${fn:substring(user.log_time,0,19) }</td>
                    <td>${user.log_ip }</td>
                    <td>${user.log_count }</td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
</c:when>

Please indicate the source of the blog post when reprinting. If you have any questions, please leave a message in the comment column. ——Kevin_Lu 2020/4/14

Guess you like

Origin www.cnblogs.com/kaml8/p/12700138.html