sessão de manutenção do android
Conclua a função de realizar a lista de usuários on-line de aplicativos no lado do servidor, seja HttpSessionListener ou HttpSessionBindingListener, todos dependem do mecanismo da sessão. No entanto, antes da saída do aplicativo, a sessão do lado do servidor é destruída, resultando na incapacidade de monitorar adequadamente o status online do usuário do aplicativo.
1. O ciclo de vida da sessão
-
Quando o servidor recebe a solicitação, ele atribui um
session会话
-
Isso
session会话
tem um tempo máximo de economiaMaxInactiveInterval
, quando o usuário不活动状态
exceder esse tempo, a sessão será destruída -
Se for uma página da web, a sessão será destruída quando o usuário sair ou sair do navegador
2. A razão pela qual o android não pode manter a sessão
-
Cada solicitação na página da web está ativa e o
session会话
tempo de redefinição será implementado para obter acesso persistente -
O lado do Android é diferente: o sessionId não está incluído no cabeçalho da solicitação, portanto, o servidor não pode identificar qual sessão está acessando nem de qual sessão a solicitação veio.
3. Resolva o problema
É recomendável que você instale o navegador FireFox, sua função de verificação é realmente fácil de usar, melhor que o Google Chrome
-
Escreva um servlet, execute o servidor, adicione um link css à página da web
-
Abra a página da Web com o FireFox e verifique
-
Observe que a verificação
Cookie:JSESSIONID=70943E03B9683A966235579F4D57892F
impressa destacadasession.getId()
concluiu que estaJSESSIONID
é a sessãosessionId
-
Como verificar o cabeçalho da solicitação do servidor de acesso ao Android? Adicione o seguinte código no 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 para iniciar uma solicitação e relatar um erro java.lang.NullPointerException, indicando que a solicitação padrão do android está sem cookies
-
Adicionar Cookie ao cabeçalho da solicitação do Android, eu uso OkHttp3 aqui
Request request = new Request.Builder() .url(url).addHeader("Cookie", "JSESSIONID=" + session_id) .post(body) .build();
-
Quanto a este session_id, você pode fazer o seguinte: o servidor recebe a solicitação de login, obtém o sessionID da sessão e o retorna para o android.O android é armazenado em SharedPreferences e é retirado quando a solicitação é enviada.
-
Use o método com cookies para acessar o servidor novamente, você pode ver a impressão
JSESSIONID
, neste momento o Android e a Web podem obter persistência da sessão
4. Verifique a persistência da sessão
-
Adicione o web.xml do projeto do servidor
<session-config> <session-timeout>1</session-timeout> </session-config>
-
Indica que o tempo máximo de economia de sessão é definido como 1 minuto, definido como 1 minuto, para facilitar a verificação
-
Adicione um ouvinte de usuário on-line, eis um plano:
//登录处理的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); } }
-
A página da web exibe a lista de usuários, diretamente application.getAttribute ("onlineUserList"), não os repetirei. A página da web é atualizada automaticamente a cada 30 segundos:
<meta http-equiv="refresh" content="30"/>
-
O aplicativo não funciona após o login, os dados da lista de usuários desaparecem após 1 minuto
-
O aplicativo opera continuamente após o login. Cada intervalo de operação é de 1 minuto e os dados da lista de usuários continuam a existir. Verificação bem sucedida
5. Outros
-
Os métodos getAttribute e setAttribute da sessão não afetarão seu ciclo de vida e ainda são considerados inativos
-
O método de obtenção da sessão com base no sessionId foi descontinuado após o Servlet 2.5 Se você ainda deseja implementar essa função, consulte https://blog.csdn.net/sihai12345/article/details/81098765. O princípio básico é manter uma por conta própria.
HashMap<String,HttpSession>
-
A lista de tipos de entidades exibida no Jsp é combinada com as expressões JSTL e EL, tanto quanto possível. É simples e claro. Não se esqueça de usar o JSTL para orientar o pacote. Exemplos:
<%@ 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>
Indique a origem da postagem do blog ao reimprimir.Se você tiver alguma dúvida, deixe uma mensagem na coluna de comentários. —Kevin_Lu 2020/4/14