web-dev-qa-db-ja.com

Tomcatの異なるアプリケーション間でセッション状態を共有する方法はありますか?

作業中のアプリケーションを2つの異なる_.war_ファイルに分割して、一方のアプリに影響を与えずに他方のアプリを更新できるようにします。各Webアプリには、異なるUI、異なるユーザー、異なる展開スケジュールがあります。

最も簡単なパスは同じセッションを共有しているようですので、アプリAがsession.setAttribute("foo", "bar")アプリBを設定すると、それを見ることができます。

同じTomcatインスタンス内の両方のアプリのHttpSession状態を共有する方法はありますか?

私たちのアプリは専用のTomcat 5.5で実行されており、同じTomcatインスタンスで実行されている他のアプリはないため、セッション共有に関するセキュリティ上の問題は問題になりません。複数のTomcatインスタンスを実行していますが、バランサーはスティッキーセッションを使用しています。

それが不可能な場合、またはこのセッション共有が本当に悪い考えである場合は、コメントを残してください。

51
Serxipc

HttpSessionを共有しないでください。ただし、他のオブジェクトを共有できます。たとえば、 JNDIを介してオブジェクトを登録 し、すべてのアプリで同じオブジェクトにアクセスできます(データベースはこれを使用して接続をプールします)。

26
Aaron Digulla

知っておくべきことの1つは、2つのWebアプリが異なるクラスローダーを使用することです。オブジェクトを共有する場合は、同じクラスローダーから同じバージョンのクラスを使用する必要があります(そうしないとLinkageErrorsが発生します)。つまり、両方のWebアプリ(たとえば、システムクラスパス)で共有されているクラスローダーにそれらを配置することを意味しますOR.

23
Alex Miller

Springを使用する場合は、Spring Sessionというプロジェクトがあります: https://github.com/spring-projects/spring-session

引用: "HttpSession-アプリケーションコンテナ(つまり、Tomcat)のHttpSessionをニュートラルな方法で置き換えることができます"

7
Luís Soares

To webappsが非常に密接に結合されているため、オブジェクトを共有する必要がある場合、なぜそれを2つに分割するのですか?それらをいくぶん独立して管理する場合でも、適切なビルド管理システムはデプロイメント用に単一のWARファイルを作成できるはずです。

AaronのようなソリューションはJNDIを使用すると動作しますが、両方のwebappが同じサーバーで実行されている場合のみです。ユニットが密結合されていて、とにかく同じサーバーで実行する場合は、単一のWARがある場合もあります

本当に独立させたい場合は、2つのデータ交換を真剣に検討します。理想的には、関連するデータのみを共有するようにしたいでしょう。このデータは、POST(または適切な場合はGET)パラメーターを介してやり取りできます。Cookieの使用を検討することもできます。

5
Kris

これを行う1つの方法は、このブログ投稿で説明されています。 Apache Tomcatでのセッション共有

概要:emptySessionPathをコネクター構成に追加し、crossContextをコンテキストに追加します

3
Ray Hulha

Tomcat 8の場合、次の構成を使用して2つのwebappでセッションを共有します。

conf/context.xml

<Context sessionCookiePath="/">
    <Valve className="org.Apache.catalina.valves.PersistentValve"/>
    <Manager className="org.Apache.catalina.session.PersistentManager">
        <Store className="org.Apache.catalina.session.FileStore" directory="${catalina.base}/temp/sessions"/>
    </Manager>
    ...
</Context>

同じ単純なwebappを2回デプロイしますlog.warおよびlog2.war

/log
/log2

/logにログインして、ユーザーを/log2に表示できるようになりました。これはTomcatのデフォルト構成では機能しません。

enter image description here

セッション値が設定され、読み取られます:

HttpSession session=request.getSession();  
session.setAttribute("name",name);

HttpSession session=request.getSession(false);  
String name=(String)session.getAttribute("name");  

このプロジェクトを例として使用しました: https://www.javatpoint.com/servlet-http-session-login-and-logout-example

ほとんどの例/ソリューションでは、より多くのセットアップ作業が必要なメモリ内データベースを使用しています。

1
flavio.donze

コンテキストルートによってサーブレットコンテキストを取得することにより、実行できます。

変数を取得するため。

request.getSession().getServletContext().getContext("/{applicationContextRoot}").getAttribute(variableName)

変数を設定する場合:

request.getSession().getServletContext().getContext("/{applicationContextRoot}").setAttribute(variableName,variableValue)

注:両方のアプリケーションを同じサーバーにデプロイする必要があります。

問題が見つかった場合はお知らせください

0
Qazi

Tomcat 8:しなければなりませんでした:<Context crossContext="true" sessionCookiePath="/"> conf/context.xml

構成属性の詳細 here

そして、値を設定するには(@Qaziの答えのように):

ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.setAttribute(variableName,variableValue)

値を取得するには:

ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.getAttribute("user"); 
0
rohith

Pythonを使用してTomcat用に セッション状態サーバー を開発しました。

このため、セッションの作成/アクセスおよび破棄のためにすでに記述されているコードを変更する必要はありません。また、セッションを処理および保存する別個のサーバー/サービスがあるため、マスタークラスターは必要ありません。この場合、セッションレプリケーション(Tomcatクラスタリングのような)はありません。むしろ、これはWebファーミング間のセッション共有です。

0
Amogh