52

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()

4

3 に答える 3

47

いいえ、サーブレットAPIは方法を提供しません。あなたは本当にそれらすべてをの助けを借りて手に入れる必要がありますHttpSessionListener。次の回答にいくつかの例があります。

于 2010-09-22T15:53:37.753 に答える
9

簡単な方法はありません。展開によって異なります。分散展開と負荷分散を導入することを決定すると、上記は失敗します。

于 2010-09-24T14:01:40.330 に答える
1

本当の答えではありませんが、古き良き時代には「javax.servlet.http.HttpSessionContext」がありましたが、バージョン2.1で削除され、明示的に置換なしで削除されました:https ://tomcat.apache.org/tomcat- 5.5-doc / servletapi / javax / servlet / http / HttpSessionContext.html

于 2015-12-07T19:05:50.270 に答える