アンドロイドセッションを維持
HttpSessionListenerまたはHttpSessionBindingListenerがすべてセッションメカニズムに依存している場合でも、サーバー側でアプリオンラインユーザーリストを実現する機能を完了します。ただし、アプリが終了する前に、サーバー側のセッションセッションが破棄されるため、アプリユーザーのオンラインステータスを適切に監視できなくなります。
1.セッションのライフサイクル
-
サーバーがリクエストを受信すると、サーバーは
session会话
-
これ
session会话
には最大保存時間がMaxInactiveInterval
あり、ユーザー不活动状态
がこの時間を超えると、セッションは破棄されます -
Webページの場合、ユーザーがログアウトするかブラウザを終了すると、セッションは破棄されます
2. Androidがセッションを維持できない理由
-
Webページ上の各要求がアクティブであり、
session会话
永続的なアクセスを実現するためにリセット時間が実装されます -
Android側は異なります。sessionIdはリクエストヘッダーに含まれていないため、サーバーはアクセスしているセッションや、リクエスト元のセッションを識別できません。
3.問題を解決する
FireFoxブラウザをインストールすることをお勧めします、そのチェック機能は本当に使いやすく、Google Chromeよりも優れています
-
サーブレットを作成し、サーバーを実行して、CSSリンクをWebページに追加します
-
FireFoxでウェブページを開いて確認します
-
強調表示
Cookie:JSESSIONID=70943E03B9683A966235579F4D57892F
された、印刷されたsession.getId()
確認により、これJSESSIONID
がセッションであることがわかりましたsessionId
-
Androidアクセスサーバーのリクエストヘッダーを確認する方法 サーブレットに次のコードを追加します。
Cookie[] Cookies = request.getCookies(); for(int i =0;i<Cookies.length;i++){ Cookie c = Cookies[i]; System.out.println(c.getName() + "=" + c.getValue()); }
-
androidを使用してリクエストを開始し、エラーjava.lang.NullPointerExceptionを報告して、AndroidのデフォルトリクエストにCookieがないことを示します
-
AndroidのリクエストヘッダーにCookieを追加します。ここではOkHttp3を使用しています
Request request = new Request.Builder() .url(url).addHeader("Cookie", "JSESSIONID=" + session_id) .post(body) .build();
-
このsession_idについては、これを行うことができます。サーバーはログイン要求を受信し、セッションのsessionIDを取得して、それをAndroid側に返します。
-
Cookieを使用してメソッドを使用してサーバーに再度アクセスすると、印刷結果を確認できます。
JSESSIONID
現時点では、AndroidとWebでセッションの永続性を実現できます。
4.セッションの永続性を確認する
-
サーバープロジェクトのweb.xmlに追加
<session-config> <session-timeout>1</session-timeout> </session-config>
-
セッションの最大保存時間が1分に設定されていることを示します。1分に設定すると、検証が容易になります
-
オンラインユーザーリスナーを追加します。これが計画です。
//登录处理的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); } }
-
Webページには、ユーザーリストが直接表示されます。application.getAttribute( "onlineUserList")です。繰り返しは行いません。Webページは30秒ごとに自動的に更新されます。
<meta http-equiv="refresh" content="30"/>
-
ログイン後にアプリが動作しない、1分後にユーザーリストデータが消える
-
アプリはログイン後も継続して動作します。各動作間隔は1分以内であり、ユーザーリストデータは存在し続けます。検証成功
5.その他
-
セッションのgetAttribute メソッドとsetAttributeメソッドは、そのライフサイクルに影響せず、非アクティブと見なされます。
-
Servlet 2.5以降、sessionIdに基づいてセッションを取得する方法は廃止されました。この機能を引き続き実装する場合は、https://blog.csdn.net/sihai12345/article/details/81098765を参照できます。基本的な原則は、自分で維持することです。
HashMap<String,HttpSession>
-
Jspに表示されるエンティティタイプのリストは、可能な限りJSTLおよびEL式と組み合わされます。シンプルで明確です。パッケージのガイドにJSTLを使用することを忘れないでください。例:
<%@ 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>
転載の際は、出典を明記の上、ご不明な点がございましたら、コメント欄にメッセージを残してください。——Kevin_Lu 2020/4/14