Как я могу поделиться переменной или объектом между двумя или несколькими сервлетами?


39

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

Я не знаю, если это зависит от используемых технологий, но я буду использовать Tomcat 5,5


Я хочу поделиться Вектор объектов простого класса (только общественных атрибутов, строки, ints и т. д.). Мое намерение состоит в том, чтобы иметь статические данные, подобные в БД, очевидно, что он будет потерян, когда Tomcat будет остановлен. (это просто для тестирования)

  0

Это во многом зависит от того, какой тип объекта/переменной он есть. Переменная относится к одному классу, и вы просто хотите получить доступ? Это постоянный? Пример будет приятным. 23 сен. 082008-09-23 20:34:14

  0

Я бы хотел, чтобы это помогло :) 23 сен. 082008-09-23 20:43:24

74

Я думаю, что вы ищете здесь запрос, сеанс или данные приложения.

В сервлете можно добавить объект в качестве атрибута объекта запроса, сеанс объекта или контекст сервлета объекта:

protected void doGet(HttpServletRequest request, HttpServletResponse response) { 
    String shared = "shared"; 
    request.setAttribute("sharedId", shared); // add to request 
    request.getSession().setAttribute("sharedId", shared); // add to session 
    this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context 
    request.getRequestDispatcher("/URLofOtherServlet").forward(request, response); 
} 

Если вы поместите его в объекте запроса он будет доступен для сервлета, который направляется, пока запрос не будет завершен:

request.getAttribute("sharedId"); 

Если вы поместите его в сессии она будет доступна для всех сервлетов идти вперед, но значение будет привязан к пользователю:

request.getSession().getAttribute("sharedId"); 

До истечения срока действия сеанса, основанного на бездействии пользователя.

сбрасывается вами:

request.getSession().invalidate(); 

Или один сервлет удаляет его из сферы действия:

request.getSession().removeAttribute("sharedId"); 

Если поместить его в контекст сервлета он будет доступен в то время как приложение работает:

this.getServletConfig().getServletContext().getAttribute("sharedId"); 

пока вы не удалите его:

this.getServletConfig().getServletContext().removeAttribute("sharedId"); 
  0

Можете ли вы расширить свой ответ на ServletContext? 23 сен. 082008-09-23 20:57:28

+1

Или 'getServletContext()' вместо 'this.getServletConfig(). GetServletContext()' ... 10 ноя. 152015-11-10 08:55:26

  0

@William Как передать что-то еще, чем String f.e. объект из класса, который я создал сам? 26 ноя. 152015-11-26 08:35:12

  0

@ Dongo Я буду честен, что с тех пор я работал с сервлетами, но если я правильно помню, в то время как я использовал String для примера, это мог быть любой объект. 27 ноя. 152015-11-27 17:56:51


1

Не могли бы вы просто поместить объект в HttpSession, а затем обратиться к нему по его имени атрибута в каждом из сервлетов?

например:

getSession().setAttribute("thing", object); 

... затем в другой сервлет:

Object obj = getSession.getAttribute("thing"); 
  0

Не нужно ли сериализовать объект для этого? 06 сен. 132013-09-06 16:56:04


7

В зависимости от объема предполагаемого использования данных.

Если данные используются только для каждого пользователя, такие как данные входа пользователя, количество попаданий страницы и т. Д., Используйте объект сеанса (httpServletRequest.getSession(). Get/setAttribute (String [, Object]))

Если это одни и те же данные для нескольких пользователей (общее количество посещений веб-страниц, рабочих потоков и т. Д.), Используйте атрибуты ServletContext. servlet.getServletCongfig(). getServletContext(). get/setAttribute (String [, Object])). Это будет работать только в том же файле war/web appliciton. Обратите внимание, что эти данные не сохраняются и при перезагрузках.

  0

Использование ServletContext может привести к неприятностям, если вы не будете осторожны. Например, вы не могли бы использовать его для наивысшего внедрения числа попаданий страницы: получить текущее количество попаданий страницы из контекста, увеличить его и установить значение в контексте. Многопоточность убивает это решение. 23 сен. 082008-09-23 21:06:49

  0

Meta critque - вопрос требует функциональности. Хранилище данных резервного копирования должно обрабатывать транзакции в любом случае. Жалобы на ACID должны привести к использованию службы данных ACID. ServletContext и Session нарушают все ACID каким-то образом. 24 сен. 082008-09-24 19:46:05


8

Поместите его в одну из трех разных областей.

запрос - продолжается жизнь запроса

сессия - продолжается жизнь сеанса пользователя

применение - длятся до тех пор, applciation не закрыт

Вы можете получить доступ ко всем этим области с помощью переменной HttpServletRequest, которая передаются в методы, которые простираются от HttpServlet class


2

Другой вариант, обмениваться данными между контекстами ...

share-data-between-servlets-on-tomcat

<Context path="/myApp1" docBase="myApp1" crossContext="true"/> 
    <Context path="/myApp2" docBase="myApp2" crossContext="true"/> 

На myApp1:

ServletContext sc = getServletContext(); 
    sc.setAttribute("attribute", "value"); 

На myApp2:

ServletContext sc = getServletContext("/myApp1"); 
    String anwser = (String)sc.getAttribute("attribute"); 

0

Вот как я это делаю с Jetty.

https://stackoverflow.com/a/46968645/1287091

использует контекст сервера, где одноэлементно записывается в процессе запуска встроенного сервера Jetty и общие среди всех WebApps для жизни сервера. Может также использоваться для совместного использования объектов/данных между webapps, предполагая, что в контекст есть только один сценарий - в противном случае вам нужно учитывать параллелизм.