java RequestDispatcher是否在一个servlet容器中处理多个Web应用程序?

s4n0splo  于 2023-05-21  发布在  Java
关注(0)|答案(3)|浏览(106)

RequestDispatcher是否可以在多个Web应用程序上工作?
我问这个问题是因为我有一个运行良好的Web应用程序,它使用RequestDispatcher而不是重定向,因此在显示错误和反馈消息时不会丢失状态。
然而,我现在需要在两个webapp之间分割一些功能,因此最初的调用是从webapp1上托管的网页进行的,调用webapp2,最终将用户返回到webapp1上托管的页面。
显然,如果webapps和webapp2位于不同的网站上,使用RequestDispatcher将是不可能的,但如果两个webapps都部署在servlet容器的同一个示例(tomcat7)中,则可能吗?

更新

得到了请求调度器部分的工作解释的答案,但我无法检索数据放在我的webapp2这就是为什么我使用它

调用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>
...

但始终显示null

更新2**

我想知道我是否误解了crossContext=“true”的实际作用。它是否使相同的HttpSession在不同的webapp中可用,或者它只是使ServletContext从一个webap到另一个webap可用,从而允许一个webapp看到另一个webapp的HttpSession?
我开始认为我所做的是一个坏主意,因为我一直热衷于使用vanilla servlet设置,从来没有想把自己绑在一个特定的实现。我想如果我解释一下为什么我一开始就不需要拆分网络应用程序,这可能会有所帮助。
我有一个网络应用程序(webapp1),这是一个关于我开发的产品的网站,并使用Google Checkout(现在的Google Wallet)购买该产品。
然后我为新产品添加了一个新的webapp(webapp2)。
然后,我试图将新产品的Google Checkout添加到webapp2中,但意识到我无法轻松做到这一点,因为Google Checkout要求我提供一个URL,一旦它处理了付款,它可以通过应用程序调用,以便我可以向用户发送许可证。该url已经设置为webapp1中的servlet,但webapp1处理产品2的付款没有意义。
一个选择是将webpp1和webapp2合并到一个webapp中,但这违背了我保持模块化的一般观点,这也意味着每次我想为一个产品做更改时,我都必须重新部署所有内容。这也意味着对webapp1的大修改,我真的不想修改,因为它工作稳定。
另一种方法是创建webapp3,然后google url可以指向它,并使用它来处理产品1和产品2的购买,这就是我所做的。但问题是,当购买产品1时,起始页面在webapp1中,一旦购买发生,我想回到webapp1中的页面,但只有webapp3有我想在webapp1中显示的刚刚购买的用户的详细信息。

vsaztqbk

vsaztqbk1#

这是由于默认情况下不可能的安全原因。您首先需要配置Tomcat,以便将当前webapp的ServletContext公开给其他webapp。这可以通过将the crossContext attribute of context.xml设置为true来完成。

<Context ... crossContext="true">

完成后,您可以使用ServletContext#getContext()通过其上下文路径获得另一个servlet上下文,最后使用ServletContext#getRequestDispatcher()获得的RequestDispatcher,就像您对HttpServletRequest#getRequestDispatcher()获得的RequestDispatcher所做的那样。
例如:

ServletContext otherContext = getServletContext().getContext("/otherContext");
otherContext.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
lvjbypge

lvjbypge2#

是的
您需要做的第一件事是为另一个Web应用程序获取ServletContext。您可以在自己的ServletContext上使用ServletContext::getContext,传递其他webapp的上下文路径。
然后,您只需在外部上下文上正常执行ServletContext::getRequestDispatcher
我还没有真正尝试过,但我100%保证它会工作。

sf6xfgos

sf6xfgos3#

我不确定不同的servlet容器。但它对同一个容器使用**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=“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 发送属性 name,并在 InterServletComm2 中接收。请让我知道如果这个答案不清楚。

相关问题