Подтвердить что ты не робот

Любой способ совместного использования состояния сеанса между различными приложениями в tomcat?

Мы хотим разбить рабочее приложение в двух разных файлах .war, чтобы иметь возможность обновлять одно приложение, не затрагивая другое. Каждый webapp будет иметь разные пользовательский интерфейс, разные пользователи и разное расписание развертывания.

Самый простой путь, по-видимому, заключается в совместном использовании одного и того же сеанса, поэтому, если приложение A установлено session.setAttribute("foo", "bar") приложение B, оно сможет его увидеть.

Есть ли способ поделиться состоянием HttpSession для обоих приложений в одном экземпляре Tomcat?

Наше приложение работает на выделенном Tomcat 5.5, других приложений, работающих на одном экземпляре tomcat, нет, поэтому любые проблемы безопасности, связанные с совместным сеансом, не являются проблемой. Мы запускаем несколько экземпляров Tomcat, но балансир использует липкие сеансы.

Если это невозможно или этот сеанс обмена - это действительно плохая идея, оставьте комментарий.

4b9b3361

Ответ 1

Вы не должны делиться HttpSession; но вы можете обмениваться другими объектами. Например, вы можете зарегистрировать объект через JNDI и получить доступ к одному и тому же объекту во всех ваших приложениях (базы данных используют это для объединения соединений).

Ответ 2

Одна вещь, о которой нужно знать, - это то, что два веб-приложения будут использовать разные загрузчики классов. Если вы хотите обмениваться объектами, они должны использовать одну и ту же версию класса из одного и того же загрузчика классов (иначе вы получите LinkageErrors). Это означает, что они помещают их в классный загрузчик, общий для обоих веб-приложений (например, для системного класса) или с помощью сериализации, чтобы эффективно сбрасывать и восстанавливать объект в правильном загрузчике классов с правильной версией класса.

Ответ 3

Если вы хотите использовать Spring, существует проект под названием Spring Session: https://github.com/spring-projects/spring-session.

Цитата: "HttpSession - позволяет заменить HttpSession нейтральным способом контейнера приложения (т.е. Tomcat)"

Ответ 4

Если веб-приложения настолько тесно связаны друг с другом, что им нужно обмениваться объектами, почему вы разбиваете их на две части? Даже если вы управляете ими несколько независимо, любая достойная система управления построением должна иметь возможность создать один файл WAR для развертывания.

Решение вроде Aaron с JNDI будет работать, но только если оба веб-приложения работают на одном сервере. Если устройства плотно связаны, и вы все равно будете запускать их на одном сервере... возможно, у вас есть одна WAR

Если вы действительно хотите, чтобы они стояли независимо, я бы серьезно изучил обмен данными между ними. В идеале вы хотели бы, чтобы они делили только релевантные данные друг с другом. Эти данные могут быть переданы обратно и обратно через POST (или GET, если это необходимо), вы можете даже рассмотреть возможность использования файлов cookie.

Ответ 6

Для Tomcat 8 я использую следующую конфигурацию для совместного использования сеанса между двумя веб-приложениями:

конф/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>

Я развернул одно и то же простое веб- приложение дважды 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

Большинство примеров/решений используют базу данных в памяти, которая требует больше работы по настройке:

Ответ 7

Вы можете сделать, взяв контекст сервлета с помощью вашего корня контекста.

Для получения переменной.

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

Для установки переменной:

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

Примечание. Оба приложения должны быть развернуты на одном сервере.

Pls сообщит мне, если вы найдете какую-либо проблему

Ответ 8

Tomcat 8: я должен был сделать: <Context crossContext="true" sessionCookiePath="/"> в conf/context.xml

подробнее об атрибутах конфигурации здесь

а затем установить значение (например, ответ @Qazi):

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

чтобы получить значение:

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

Ответ 9

Я разработал сервер состояния сеанса для Tomcat, используя Python.

В связи с этим мне не нужно изменять код, уже написанный для создания/доступа и уничтожения сессии. Также существует отдельный сервер/служба, которая обрабатывает и хранит сеанс, поэтому не требуется мастер-кластер. В этом случае нет репликации сеансов (как в кластеризации tomcat), скорее это совместное использование сеансов между веб-фермерством.

Ответ 10

Вы не должны разбить приложение таким образом, чтобы иметь высокую доступность. Вы можете развернуть все приложение во многих экземплярах tomcat.