wake-up-neo.com

Wie kann ich den Sitzungsstatus zwischen verschiedenen Anwendungen in Tomcat freigeben?

Wir möchten eine funktionierende Anwendung in zwei verschiedene .war-Dateien aufteilen, um eine App aktualisieren zu können, ohne die andere zu beeinflussen. Jede Webapp hat eine unterschiedliche Benutzeroberfläche, unterschiedliche Benutzer und einen unterschiedlichen Bereitstellungszeitplan. 

Der einfachste Pfad scheint die gleiche Sitzung zu teilen. Wenn App A session.setAttribute("foo", "bar") gesetzt ist, kann App B sie sehen.

Gibt es eine Möglichkeit, den Status HttpSession für beide Apps in derselben Tomcat-Instanz gemeinsam zu nutzen?

Unsere App läuft auf einem dedizierten Tomcat 5.5. Es werden keine anderen Apps auf derselben Tomcat-Instanz ausgeführt. Daher sind Sicherheitsbedenken hinsichtlich der Sitzungsfreigabe kein Problem. Wir führen mehrere Tomcat-Instanzen aus, aber der Balancer verwendet ständige Sitzungen.

Wenn dies nicht möglich ist oder diese Sitzung teilen eine wirklich schlechte Idee ist, hinterlassen Sie bitte einen Kommentar.

51
Serxipc

Sie sollten HttpSession nicht freigeben. Sie können jedoch auch andere Objekte freigeben. Sie können beispielsweise ein Objekt über JNDI registrieren und auf das gleiche Objekt in allen Ihren Apps zugreifen (Datenbanken verwenden dies, um Verbindungen zu bündeln).

25
Aaron Digulla

Zu beachten ist, dass zwei Web-Apps unterschiedliche Klassenladeprogramme verwenden. Wenn Sie Objekte gemeinsam nutzen möchten, müssen sie dieselbe Version der Klasse aus demselben Klassenladeprogramm verwenden (andernfalls erhalten Sie LinkageErrors). Dies bedeutet, dass sie entweder in einen Klassenlader gestellt werden, der von beiden Web-Apps gemeinsam genutzt wird (z. B. Systemklassenpfad) OR, indem die Serialisierung verwendet wird, um das Objekt im richtigen Klassenlader mit der richtigen Version der Klasse effektiv zu entleeren und wiederherzustellen. 

22
Alex Miller

Wenn Sie Spring verwenden möchten, gibt es ein Projekt namens Spring Session: https://github.com/spring-projects/spring-session

Zitat: "HttpSession - Ermöglicht das Ersetzen der HttpSession in einem Anwendungscontainer (d. H. Tomcat) auf neutrale Weise."

7
Luís Soares

Wenn die Webapps so eng miteinander verbunden sind, dass sie Objekte gemeinsam nutzen müssen, warum teilen Sie sie dann in zwei Teile auf? Selbst wenn Sie sie einigermaßen unabhängig verwalten, sollte jedes anständige Build-Verwaltungssystem in der Lage sein, eine einzige WAR-Datei für die Bereitstellung zu erstellen.

Eine Lösung wie Aaron schlägt mit JNDI vor, funktioniert jedoch nur, wenn beide Webapps auf demselben Server ausgeführt werden. Wenn die Einheiten eng miteinander verbunden sind und Sie sie trotzdem auf demselben Server ausführen, kann es auch einen einzigen WAR geben

Wenn Sie wirklich wollen, dass sie unabhängig stehen, würde ich den Datenaustausch zwischen beiden ernsthaft prüfen. Im Idealfall möchten Sie, dass sie nur relevante Daten miteinander teilen. Diese Daten können über die Parameter POST (oder GET, wenn dies angemessener ist) hin- und hergegeben werden. Möglicherweise verwenden Sie auch Cookies. 

5
Kris

Eine Möglichkeit hierzu ist in diesem Blogbeitrag beschrieben: Sitzungsfreigabe in Apache Tomcat

Zusammenfassung: Fügen Sie emptySessionPath der Connector-Konfiguration und crossContext zum Kontext hinzu

3
Ray Hulha

Für Tomcat 8 verwende ich die folgende Konfiguration, um eine Sitzung über 2 Webanwendungen zu teilen:

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>

Ich setze dieselbe einfache Webanwendung zweimal ein log.war und log2.war :

/log
/log2

Ich kann mich jetzt bei /log anmelden und den Benutzer in /log2 anzeigen lassen. Dies funktioniert nicht mit der Tomcat-Standardkonfiguration.

 enter image description here 

Der Sitzungswert wird gesetzt und gelesen:

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

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

Ich habe dieses Projekt als Beispiel verwendet: https://www.javatpoint.com/servlet-http-session-login-and-logout-example

Die meisten Beispiele/Lösungen verwenden eine In-Memory-Datenbank, die mehr Einrichtungsarbeit erfordert:

1
flavio.donze

Sie können dies tun, indem Sie den Servlet-Kontext von Ihrem Kontextstammverzeichnis nehmen.

Zum Abrufen von Variablen.

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

Zum Einstellen der Variablen:

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

Hinweis: Beide Anwendungen sollten auf demselben Server bereitgestellt werden.

Bitte lassen Sie mich wissen, wenn Sie ein Problem finden

0
Qazi

Tomcat 8: Ich musste folgendes tun: <Context crossContext="true" sessionCookiePath="/"> in conf/context.xml

weitere Details zu den Konfigurationsattributen hier

und dann, um den Wert einzustellen (wie @ Qazis Antwort):

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

um den Wert zu erhalten:

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

Ich habe Session State Server für Tomcat mit Python entwickelt.

Aus diesem Grund muss ich den bereits erstellten Code zum Erstellen/Zugreifen auf und Zerstören von Sitzungen nicht ändern. Da es einen separaten Server/Dienst gibt, der die Sitzung behandelt und speichert, ist kein Master-Cluster erforderlich. In diesem Fall gibt es keine Sitzungsreplikation (wie beim Tomcat-Clustering), sondern es ist eine Sitzungsfreigabe zwischen Web-Farming.

0
Amogh