Tomcat ServletContext против JNDI для обмена данными сеанса между несколькими файлами войны - PullRequest
2 голосов
/ 12 февраля 2012

У меня есть веб-приложение на основе Struts, структура которого аналогична приведенной ниже. (Не это просто пример)

$TOMCAT_HOME/webapps/myapp
            |-css
                |-myapp.css
            |-js
                |-myapp.js
            |-forum
                |-index.jsp
                |-list.jsp
                |-users.jsp
            |-Articles
                |-index.jsp
                |-ListArticles.jsp
            |-Guestbook
                |-viewGuestBook.jsp
                |-AddnewEntry.jsp
            |-WEB-INF
                |-classes
                    com
                     |-myapp
                        |-forum
                            |-DisplayForum.class
                            |-ListUsers.class
                        |-article
                            |-ArticleList.class
                            |-AddArticle.class
                        |-guestbk
                            |-LoadGuestBook.class
                            |-ProcessGuestBook.class

В настоящее время приложение построено с использованием ANT и развернуто на сервере приложений Tomcat в виде единого файла war (с именем myapp.war). Я хотел бы разделить приложение так, чтобы оно развертывалось с использованием нескольких файлов war для каждого модуля. (то есть forum.war, Articles.war и guestbook.war). Содержимое нового военного файла будет содержать только файлы, относящиеся к модулю. Например, файл forum.war будет содержать

$TOMCAT_HOME/webapps/forum              
            |-forum
                |-index.jsp
                |-list.jsp
                |-users.jsp             
            |-WEB-INF
                |-classes
                    com
                     |-myapp
                        |-forum
                            |-DisplayForum.class
                            |-ListUsers.class

В этом подходе есть пара моментов, в которых я не уверен.

Общие статические ресурсы

Файлы * .css и * .js являются общими для каждого файла войны. Если у меня разные военные файлы, у меня будет копия css-файлов в каждом военном файле. Есть ли способ, которым я могу доставить файлы ресурсов (CSS, JS, статические файлы) в общем подходе, чтобы они были общими. Я думаю, что, возможно, мне следует включить новый файл war под названием common.war и включить общие статические данные. (Я думаю, что другие военные файлы могут обращаться к этим файлам с помощью URL, поскольку они являются статическими ресурсами. Верно?)

Общие классы

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

Объект UserSession делает несколько вещей, таких как

  • Подтверждение логина пользователя
  • Отслеживать активность пользователя
  • Записать историю входа пользователя в базу данных
  • И еще ...

Мне нужны все военные файлы (приложения / модули), чтобы иметь доступ к объекту UserSession, но только один связан с каждым сеансом. Как мне спроектировать это так, чтобы сеанс пользователя охватывал разные военные файлы?

Я читал о том, как делиться объектами, и предложил два варианта

  • Общий объект через JNDI
  • Общий объект через Tomcat ServletContext

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

User1 входит в систему - UserSession хранится в ServletContext User2 входит в систему - где я могу хранить объект UserSession User2?

В данный момент я сохраняю sessionID в HTTPSession и объект UserSession в HashTable.

HttpSession session = request.getSession(true);
UserSession userSession = getUserSession(session.getId());

Получает ли User1 одинаковый идентификатор сессии независимо от того, к какому файлу он / она обращается? Если это так, могу ли я сохранить другой объект списка в ServletContext, который содержит идентификаторы сеанса?

Я также видел ссылки на совместное использование объектов с использованием JNDI. Я не очень знаком с JNDI. Я использовал JNDI для источников данных, но это далеко. Как именно это будет работать? Я был бы признателен, если бы кто-нибудь показал мне пример, показывающий, как JNDI можно использовать для обмена данными. Правда ли, что JNDI - лучший подход и почему?

И, наконец, где будет находиться файл UserSession.class? Я знаю, что могу поместить его в файл jar в $TOMCAT_HOME/lib, но обычно это не рекомендуется. Проблема, однако, в том, что если он находится в папке WEB-INF/lib одного из военных файлов, к нему не может получить доступ любой другой военный файл.

Буду признателен за некоторые предложения / предложения. Мне было бы интересно узнать, какую стратегию вы используете для развертывания приложения, состоящего из нескольких военных файлов.

Спасибо

Редактировать

Хорошо, я забыл упомянуть, почему я хочу разделить файл войны. По сути, у нас есть несколько команд разработчиков. У нас были ситуации, когда одна команда работала над определенной областью приложения, а другая команда работала над другой областью.

Например, предположим следующий сценарий -

Team1 работает над модулем Форумы, который должен быть выпущен в следующем месяце. Team2 попросили внести изменения в Статьи и должны быть выпущены на следующей неделе.

Если Team1 проверила свой код и выполняет системные / интеграционные тесты, которые займут больше недели, Team2 набивается, поскольку им приходится ждать.

Подобные проблемы обычно решаются с помощью ветвления, но мы стараемся избегать ветвления, так как это создает много сложностей с объединением, которые мы решили избежать ветвления.

Другая причина в том, что у нас есть старое приложение, которое я собираюсь использовать в этом приложении. Старое приложение, основанное на чистом HTTPServlet. Т.е. не основано ни на какой структуре (то есть структурах, весне и т. Д.). Если я хочу интегрировать его с моим существующим приложением, мне нужно будет использовать session / servletcontext.

Кроме того, многие люди скептически относятся к тому факту, что если вы вносите простое изменение (например, добавляете новое определение таблицы стилей в один файл CSS), вам придется пересобрать и заново развернуть все приложение.

Другие причины включают

  • Может упростить масштабирование / балансировку нагрузки - (возможно?) Не уверен насчет этого. Я думаю с точки зрения развертывания каждого файла войны на другой сервер / кластер.
  • Снижает требования к памяти PERMGEN
  • и т.д ...

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

Я не уверен, что вы правильно поняли, но HttpSession отличается для каждого пользователя (сеанс браузера), а также для каждого приложения, AFAIK, поэтому вы не можете использовать его для обмена данными.

По сути, вам нужна связь между вашими веб-приложениями. У вас может быть одна война, чтобы действовать как менеджер данных для вашей UserSession, и все другие войны, связанные с этой. Приложение диспетчера данных должно предоставлять услугу, например, UserSessionManager, к которому можно получить доступ через другие приложения.

JNDI является традиционным решением для этого. У Spring есть некоторые помощники для этого, но JNDI API также не слишком сложен. В войне с диспетчером данных вы можете сделать что-то подобное в методе инициализации:

DataManager mgr = new DataManagerImpl(...);
InitialContext ic = new InitialContext();
ic.rebind("java:global/env/datamanager", mgr);

Интерфейс и используемые вами объекты данных должны быть помещены в банку, которая используется во всех «клиентских» войнах, реализация только в войне с диспетчером данных. В войнах вашего клиента вы можете сделать:

InitialContext ic = new InitialContext();
DataManager mgr = (DataManager)ic.lookup("java:global/env/datamanager");

Надеюсь, это поможет, Герт.

1 голос
/ 13 февраля 2012

Если Team1 проверила свой код и выполняет системные / интеграционные тесты, которые займут больше недели, Team2 забиты, так как им приходится ждать.

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

Ну, вот твоя проблема.Это именно то, для чего разветвление.Если это вызывает у вас проблемы, то ответ состоит в том, чтобы решить эти проблемы, а не избегать разветвлений полностью.Это может быть так же просто, как перейти на лучший VCS.(Какой из них вы используете прямо сейчас?)

Кроме того, многие люди скептически относятся к тому факту, что если вы сделаете простое изменение (например, добавите новое определение таблицы стилей в один файл CSS)), вам нужно пересобрать и заново развернуть все приложение.

Такова природа веб-приложений на Java.Если вы поместите файлы CSS в отдельную войну, вам все равно придется перестроить и заново развернуть эту войну.А с несколькими войнами процесс станет более сложным, а не менее.

В любом случае, каждая Java IDE позволяет вам делать это одним нажатием клавиши, поэтому я не вижу, в чем дело.

Может упростить масштабируемость / балансировку нагрузки - (возможно?)

Возможно.Но вы знаете, что они говорят о преждевременной оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...