1

RequestDispatcher 是否可以在多个 webapps 上工作?

我之所以问,是因为我有一个使用 RequestDispatcher 而不是重定向的 webapp 运行良好,因此在显示错误和反馈消息时状态不会丢失。

但是我现在需要在两个 webapps 之间拆分一些功能,所以初始调用是从 webapp1 上托管的网页进行的,调用 webapp2 最终将用户返回到 webapp1 上托管的页面。

显然,如果 webapps 和 webapp2 使用 RequestDispatcher 在不同的网站上是不可能的,但是如果两个 webapps 都部署在同一个 servlet 容器实例中(tomcat 7)

更新

让请求调度程序部分按照答案中的说明工作,但无法检索放入我的 webapp2 的数据,这就是我使用它的原因

IE

webapp2 调用,进行一些处理,然后分派到 webapp1 上的 jsp

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); 
}

webapp2 jsp 文件包含

...
<p>Email(<%=((String)session.getAttribute("DATA"))%>)</p>
...

但总是显示空

更新 2 **

我想知道我是否误解了 crossContext="true" 的实际作用。它是否使相同的 HttpSession 在不同的 webapps 中可用,或者它只是使 ServletContext 从一个 webap 可用到另一个,从而允许一个 webapp 看到另一个 webapp 的 HttpSessions?

我开始认为我正在做的事情是个坏主意,因为我一直热衷于使用 vanilla servlet 设置,并且从不想将自己束缚于特定的实现。我认为如果我解释为什么我一开始就不需要拆分 webapps 可能会有所帮助。

我有一个 webapp (webapp1),这是一个关于我开发的产品的网站,以及使用 Google Checkout(现在的 Google Wallet)购买该产品的代码。

然后我添加了为新产品(webapp2)创建了一个新的 webapp。

然后,我尝试将新产品的 Google Checkout 添加到 webapp2 中,但意识到我不能轻易做到这一点,因为 Google Checkout 要求我提供一个 URL,一旦它处理了付款,它就可以由应用程序调用,这样我就可以向用户发送一个执照。该 url 已经设置为 webapp1 中的一个 servlet,但是 webapp1 处理产品 2 的付款是没有意义的。

一种选择是将 webpp1 和 webapp2 合并到一个 webapp 中,但这违背了我保持模块化的一般观点,这也意味着每次我想为一个产品 Id 进行更改时都必须重新部署所有内容。这也意味着对 webapp1 的重大修改,我真的不想修改它,因为它工作且稳定。

另一种方法是创建 webapp3,然后 google url 可以指向它,并使用它来处理产品 1 和产品 2 的购买,这就是我所做的。但问题是购买产品 1 时,起始页面位于 webapp1 中,一旦购买完成,我想返回 webapp1 中的页面,但只有 webapp3 有我想要的刚刚购买的用户的详细信息在 webapp1 的页面上显示。

4

3 回答 3

2

这是由于安全原因,默认情况下是不可能的。您需要先配置 Tomcat 以启用将ServletContext当前 webapp 暴露给其他 webapps。这是通过设置tocrossContext属性context.xml来完成的true

<Context ... crossContext="true">

完成后,您可以使用ServletContext#getContext()通过其上下文路径获取另一个 servlet 上下文,最后使用RequestDispatcher通过ServletContext#getRequestDispatcher()通常方式获得的 。

例如

ServletContext otherContext = getServletContext().getContext("/otherContext");
otherContext.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
于 2012-11-18T22:31:40.890 回答
1

是的。

您需要做的第一件事是ServletContext为另一个 webapp 获取一个。你可以ServletContext::getContext自己做ServletContext,传递另一个 webapp 的上下文路径。

然后,您只需ServletContext::getRequestDispatcher在外国环境中照常行事。

我实际上还没有尝试过,但我 100% 保证它会起作用。

于 2012-11-17T23:20:22.997 回答
1

我不确定不同的 servlet 容器。但它通过使用 getServletContext().getContext()方法适用于同一个容器。

首先,您需要在以下文件中进行更改

(Windows) C:\Program Files\Apache Software Foundation\Tomcat 7.0\conf\context.xml 将 crossContext 的值设置为 true。

上下文.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="true"

假设您有两个名为InterServletComm1InterServletComm2的 Web 应用程序,每个 Web 应用程序中分别 有 Servlet Servlet1Servlet1。然后每个 servlet 中的代码如下:

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中接收。如果这个答案不清楚,请告诉我。

于 2013-10-09T13:18:25.617 回答