web-dev-qa-db-ja.com

WebアプリケーションのすべてのHttpSessionオブジェクトのリストを取得するにはどうすればよいですか?

0個以上の有効なHttpSessionオブジェクトが関連付けられた、実行中のJavaベースのWebアプリケーションがあるとします。有効なHttpSessionオブジェクトの現在のリストにアクセスする方法が必要です。私はHttpSessionListenerを実装し、それを使用してアプリケーションスコープの属性に格納されているセッションID値のリストに追加できると考えていましたが、その後、フックとしてリストをセッションとして更新します無効にされ、誰が他に何を知っている。

独自のソリューションを作成する前に、質問をする必要があると考えました。
サーブレットAPIは、無効化されていないセッションオブジェクトの完全なリストにアクセスする手段を提供しますか?

Tomcat 6.xをWebアプリケーションコンテナとして使用し、MyFaces 1.2.x(JSF)ライブラリを使用しています。

[〜#〜] solution [〜#〜]
これらの既存の質問で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);
    }
}
_

私をいらいらさせ続ける1つのことは、Tomcatを再起動するとどうなるかです。セッションをディスクにシリアル化しないようにTomcatが適切に構成されていない限り、Tomcatはそうします。 Tomcatが再び起動すると、HttpSessionオブジェクト(およびそれらと一緒のSessionDataオブジェクト)のシリアル化が解除され、セッションが再び有効になります。ただし、シリアル化/逆シリアル化はHttpSessionリスナーイベントを完全に回避するため、再起動後にSessionDataへの逆シリアル化された参照を管理対象オブジェクトのセットに戻すことはできません。

私は顧客の組織でTomcatの実稼働構成を制御することはできないため、Tomcatが期待どおりに実行されるとは思いません。

私の回避策は、HttpSession作成時間を、リクエストを受信したときのアプリケーションの起動時間と比較することです。アプリケーションの起動時間より前にセッションが作成された場合、invalidate()を呼び出すと、ユーザーは何が起こったのかを説明するエラー/警告ページに送られます。

ServletContextListenerを実装し、リスナーのcontextInitialized()メソッド内からアプリケーションスコープのオブジェクト内に現在の時刻を格納することにより、アプリケーションの起動時間を取得します。

49
Jim Tough

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

46
BalusC

直接的な方法はありません。展開に依存します。分散展開と負荷分散の導入を決定すると、上記は失敗します。

9
gertas

実際には答えではありませんが、昔は "javax.servlet.http.HttpSessionContext"がありましたが、バージョン2.1で削除されました。代わりに明示的に: https://Tomcat.Apache。 org/Tomcat-5.5-doc/servletapi/javax/servlet/http/HttpSessionContext.html

1
Nathan Crause