Работает ли RequestDispatcher над несколькими веб-приложениями в одном контейнере сервлетов?

Работает ли RequestDispatcher через несколько веб-приложений?

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

Однако теперь мне нужно разделить некоторые функции между двумя веб-приложениями, поэтому первоначальный вызов выполняется с веб-страницы, размещенной в webapp1, вызывает webapp2, которая в конечном итоге возвращает пользователя на страницу, размещенную в webapp1.

Ясно, что если бы webapps и webapp2 находились на разных сайтах, использовать RequestDispatcher было бы невозможно, но это так, если оба веб-приложения были развернуты в одном и том же экземпляре контейнера сервлета (tomcat 7)

Обновить

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

т.е.

Вызывается webapp2, выполняет некоторую обработку, а затем отправляет jsp на webapp1.

protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
{

    HttpSession userSession = request.getSession(true);
    String emailAddress = ......
    String nextPage     = /finish.jsp
    userSession.setAttribute("DATA", emailAddress);
    ServletContext otherContext = getServletContext().getContext("/webapp1");
    otherContext.getRequestDispatcher(nextPage).forward(request, response); 
}

JSP-файл webapp2 содержит

...
<p>Email()</p>
...

но всегда показывает ноль

 Обновление 2 **

Мне интересно, не понимаю ли я, что такое crossContext = "правда" на самом деле Делает ли он один и тот же HttpSession доступным в разных веб-приложениях, или он просто делает ServletContext из одного веб-сайта доступным для другого и, следовательно, позволяет одному веб-приложению видеть HttpSessions другого веб-приложения?

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

У меня было одно веб-приложение (webapp1), это был веб-сайт о продукте, который я разрабатываю, и код для покупки этого продукта с помощью Google Checkout (теперь Google Wallet).

Затем я добавил созданный новый веб-приложение для нового продукта (webapp2).

Затем я попытался добавить Google Checkout для нового продукта в webapp2, но понял, что не могу сделать это легко, потому что Google Checkout требует от меня предоставить ему URL-адрес, по которому он может вызывать приложение после обработки платежа, чтобы я мог затем отправить пользователю лицензия. URL был уже установлен на сервлет в webapp1, но это неДля webapp1 имеет смысл обрабатывать платежи для продукта 2.

Один из вариантов состоял в том, чтобы объединить webpp1 и webapp2 в одно webapp, но это противоречит моему общему мнению о сохранении модульности, это также означало бы, что каждый раз, когда я хотел бы сделать изменения для одного продукта, мне пришлось бы перераспределять все. Это также означало большие изменения в webapp1, которые я действительно не хотел изменять, поскольку он работал и работал стабильно.

Альтернативой было создание webapp3, и затем URL-адрес Google может указывать на это и использовать его для обработки покупок продукта 1 и продукта 2, что я и сделал. Но проблема в том, что при покупке продукта 1 начальная страница находится в webapp1, и после совершения покупки я хочу вернуться на страницу в webapp1, но только в webapp3 есть данные о пользователе, который только что совершил покупку, которую я хотел для отображения на странице в webapp1.

Ответы на вопрос(3)

Решение Вопроса

сначала настроить Tomcat, чтобы включитьServletContext текущего веб-приложения для других веб-приложений. Это должно быть сделано путем установкиcrossContext атрибутcontext.xml кtrue

<context ...="" crosscontext="true">
</context>

После этого вы можете использоватьServletContext#getContext() чтобы получить другой контекст сервлета по его контекстному пути и, наконец, использоватьRequestDispatcher как полученоServletContext#getRequestDispatcher() обычный способ.

Например.

ServletContext otherContext = getServletContext().getContext("/otherContext");
otherContext.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
 Paul Taylor19 нояб. 2012 г., 14:27
Прямо под тем же доменом вы имеете в виду тот же экземпляр tomcat, я установил путь к cookie, как описано вstackoverflow.com/questions/3980392/...
 Paul Taylor19 нояб. 2012 г., 13:47
Ваш ответ помечен правильно, но, пожалуйста, дайте мне подсказку, как хранить в области применения
 BalusC19 нояб. 2012 г., 13:50
Область применения представлена атрибутамиServletContext (например, область видимости сеанса представлена атрибутамиHttpSession и запросить область темHttpServletRequest .. ты видишь это сейчас? :) ) Смотрите такжеstackoverflow.com/questions/3106452/...
 BalusC19 нояб. 2012 г., 14:24
Объем сеанса представлен атрибутамиHttpSession, HTTP-сессия другого веб-приложенияt такой же, как сеанс HTTP текущего веб-приложения, если только он не выполняется в одном домене, а сервер явно не настроен для установки пути файла cookie сеанса./
 Paul Taylor19 нояб. 2012 г., 14:33
Ах, я не могу использовать атрибуты ServletContext, так как эта переменная для каждого пользователя, поэтому я просто хочу, чтобы она существовала для этого взаимодействия пользователейПосмотрим дальше, как заставить работать HttpSession
 BalusC19 нояб. 2012 г., 13:45
Запрос текущего веб-приложения во время отправки заменяется запросом, специфичным для другого веб-приложения. Это'в противном случае содержали неверную информацию, что могло привести к неприятным ошибкам. Просто храните общие данные в области приложения или БД. Вы можете передать уникальный идентификатор в качестве параметра запроса.
 Paul Taylor19 нояб. 2012 г., 13:19
Привет, спасибо, что часть работает, но причина, по которой я хочу это сделать, заключается в том, что webapp2 может поместить некоторые данные в объект сеанса с помощью putAttribute, а затем вывести их в webapp1, но webapp1 'не могу найти данные, яуточню вопрос с примером
 BalusC19 нояб. 2012 г., 13:22
Это, конечно, будет работать, только если они используют один и тот же сеанс HTTP. Это также необходимо настроить на стороне сервера. Если все веб-приложения работают в одном домене, просто установитеsessionCookiePath атрибут всех контекстов веб-приложения/ разрешить всем веб-приложениям использовать один и тот же сеанс HTTP. Если это, однако, создает проблемы проектирования, то вместо этого сохраните его в общем хранилище данных, таком как область приложения или БД.
 Paul Taylor19 нояб. 2012 г., 14:23
Ну да ладно, теперь я понимаю ApplicationScope, и я мог бы это использовать, но я думал, что использую область действия Session, а не RequestScope, и, следовательно, все еще буду существовать через веб-приложения.
 Paul Taylor19 нояб. 2012 г., 13:38
Я думал, что сессия была сохранена с запросом, нет? Только что попробовалstackoverflow.com/questions/3980392/... но не имеет никакого значения

Первое, что вам нужно сделать, это получитьServletContext для другого веб-приложения. Вы делаете это сServletContext::getContext самостоятельноServletContext, передавая контекстный путь другого веб-приложения.

Затем вы просто делаетеServletContext::getRequestDispatcher как обычно в иностранном контексте.

У меня нетЯ на самом деле пробовал это, но я на 100% гарантирую, что это будет работать.

 Paul Taylor19 нояб. 2012 г., 21:27
На самом деле это не сработало, пока я не установил поле crossContext, как описано в другом ответе.

го же контейнера с помощьюgetServletContext (). getContext () метод.

Сначала вам нужно внести изменения в файл ниже

(Windows) C: \ Program Files \ Apache Software Foundation \ Tomcat 7.0 \ conf \ context.xml Установите для свойства crossContext значение true.

context.xml

<context crosscontext="true">

    <!-- Default set of monitored resources -->
    <watchedresource>WEB-INF/web.xml</watchedresource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->

</context>

Обратите внимание, чтоcrossContext =»правда".

Предположим, у вас есть два веб-приложения с именемInterServletComm1 а такжеInterServletComm2 имея сервлетыservlet1 а такжеservlet1 в каждом веб-приложении соответственно. Тогда код в каждом сервлете выглядит следующим образом:

Servlet1.java

package interServletComm1;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Servlet1
 */
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlet1() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();

        request.setAttribute("name", "WebApp1");
        ServletContext context = getServletContext().getContext("/InterServletComm2");
        RequestDispatcher rd = context.getRequestDispatcher("/Servlet2");
        rd.forward(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

Servlet2.java

package interServletComm2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Servlet2
 */
@WebServlet("/Servlet2")
public class Servlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Servlet2() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        response.setContentType("text/html");
        PrintWriter pw = response.getWriter();
        String name = (String) request.getAttribute("name");
        pw.println("This is web application 2.");
        pw.println("<br>The value received from web application one is: " + name);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

Выше код отправляет атрибутназвание отInterServletComm1 и он получен вInterServletComm2, Пожалуйста, дайте мне знать, если этот ответ не ясен.

Ваш ответ на вопрос