0個以上の有効なHttpSessionオブジェクトが関連付けられた実行中のJavaベースのWebアプリケーションがあるとします。HttpSession有効なオブジェクトの現在のリストにアクセスする方法が必要です。を実装し、HttpSessionListenerそれを使用して、アプリケーションスコープの属性に格納されているセッションID値のリストに追加できると考えていましたが、セッションが無効になっているため、リストを更新することになりました。そうしないと。
独自のソリューションを作成する前に、次の質問をする必要があると思い
ました。サーブレットAPIは、無効化されていないセッションオブジェクトの完全なリストにアクセスするための何らかの手段を提供しますか?
WebアプリケーションコンテナとしてTomcat6.xを使用しており、MyFaces 1.2.x(JSF)ライブラリを使用しています。
解決
策私は、BalusCがこれらの既存の質問で説明したのと同様のアプローチに従いました。
SessionDataを実装するためにクラスごとに変更しましたHttpSessionBindingListener。バインディングイベントが発生すると、オブジェクトはすべてのオブジェクトのセットに自分自身を追加または削除しSessionDataます。
@Override
public void valueBound(HttpSessionBindingEvent event) {
// Get my custom application-scoped attribute
ApplicationData applicationData = getApplicationData();
// Get the set of all SessionData objects and add myself to it
Set<SessionData> activeSessions = applicationData.getActiveSessions();
if (!activeSessions.contains(this)) {
activeSessions.add(this);
}
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
HttpSession session = event.getSession();
ApplicationData applicationData = getApplicationData();
Set<SessionData> activeSessions = applicationData.getActiveSessions();
if (activeSessions.contains(this)) {
activeSessions.remove(this);
}
}
私を苛立たせ続けているのは、Tomcatを再起動したときに何が起こるかということです。セッションをディスクにシリアル化しないようにTomcatが適切に構成されていない限り、シリアル化されます。Tomcatが再起動すると、HttpSessionオブジェクト(およびSessionDataオブジェクトと一緒のオブジェクト)が逆シリアル化され、セッションが再び有効になります。ただし、シリアル化/逆シリアル化はリスナーイベントを完全に回避するため、再起動後に、逆シリアル化された参照を管理対象のオブジェクトセットに適切に戻すHttpSession機会がありません。SessionData
私は顧客の組織でTomcatの実稼働構成を制御できないため、期待どおりに実行されるとは想定できません。
HttpSession私の回避策は、リクエストを受信したときの作成時間とアプリケーションの起動時間を比較することです。アプリケーションの起動時間より前にセッションが作成された場合は、電話をかけるinvalidate()と、何が起こったかの説明が記載されたエラー/警告ページが表示されます。
を実装し、リスナーServletContextListenerのメソッド内からアプリケーションスコープのオブジェクト内に現在の時刻を格納することで、アプリケーションの起動時刻を取得します。contextInitialized()