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

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

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


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


person David Ameller    schedule 23.09.2008    source источник
comment
Это во многом зависит от того, какой это объект/переменная. Принадлежит ли переменная одному классу, и вам просто нужен доступ? Это константа? Пример был бы хорош.   -  person Swati    schedule 24.09.2008


Ответы (6)


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

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

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");
person William    schedule 23.09.2008
comment
Не могли бы вы расширить свой ответ для ServletContext? - person David Ameller; 24.09.2008
comment
Или getServletContext() вместо this.getServletConfig().getServletContext()... - person Elrond_EGLDer; 10.11.2015
comment
@William Как я могу передать что-то еще, кроме String f.e. объект из класса, который я создал сам? - person Stanko; 26.11.2015
comment
@Dongo Честно говоря, я давно не работал с сервлетами, но если я правильно помню, когда я использовал String для примера, это мог быть любой объект. - person William; 27.11.2015

Поместите его в один из 3-х разных прицелов.

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

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

приложение - длится до тех пор, пока приложение не будет закрыто

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

person bpapa    schedule 23.09.2008

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

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

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

person shemnon    schedule 23.09.2008
comment
Использование ServletContext может легко привести к неприятностям, если вы не будете осторожны. Например, вы не могли бы использовать его для реализации счетчика посещений страницы наивным способом: получить текущий счетчик посещений страницы из контекста, увеличить его и установить значение в контексте. Многопоточность убивает это решение. - person JavadocMD; 24.09.2008
comment
Мета-критика - вопрос заключается в том, что функциональность резервного хранилища данных должна обрабатываться через транзакции в любом случае. Жалобы на ACID должны привести к использованию службы данных ACID. ServletContext и Session каким-то образом нарушают весь ACID. - person shemnon; 24.09.2008

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

обмен данными между сервлетами на коте

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

В моем приложении1:

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

В моем приложении2:

  ServletContext sc = getServletContext("/myApp1");
  String anwser = (String)sc.getAttribute("attribute");
person ggrandes    schedule 17.04.2013

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

e.g:

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

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

Object obj = getSession.getAttribute("thing");
person yalestar    schedule 23.09.2008

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

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

Использует контекст сервера, где синглтон записывается во время запуска встроенного сервера Jetty и используется всеми веб-приложениями на протяжении всего срока службы сервера. Также может использоваться для обмена объектами/данными между веб-приложениями при условии, что в контексте есть только один писатель, в противном случае вам нужно помнить о параллелизме.

person Reed Sandberg    schedule 27.10.2017