RequestDispatcher是否在一个servlet容器中处理多个webapps?
RequestDispatcher是否可以处理多个Web应用程序?
我问,因为我有一个单一的webapp工作正常,使用RequestDispatcher而不是重定向,所以在显示错误和反馈消息时状态不会丢失。
但是我现在需要在两个webapps之间拆分一些function,因此初始调用是从webapp1上托管的网页进行的,调用webapp2最终将用户返回到webapp1上托管的页面。
显然,如果webapps和webapp2在不同的网站上使用RequestDispatcher是不可能的,但是如果两个webapps都部署在servlet容器的同一个实例中(tomcat 7)
更新
得到请求调度程序部分工作,如在答案中解释,但我无法检索放入我的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文件包含
... Email()
...
但始终显示null
更新2 **
我想知道我是否误解了crossContext =“true”实际上是做什么的。 它是否可以在不同的webapps中使用相同的HttpSession,或者只是将ServletContext从一个webap可用到另一个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中,但这违背了我保持模块化的一般观点,这也意味着我希望为一个产品生成chn的时间必须重新部署所有内容。 这也意味着对webapp1的大修改,我真的不想修改它,因为它工作稳定。
另一种方法是创建webapp3然后谷歌url可以指向这个,并使用它来处理产品1和产品2的购买,这是我所做的。 但问题是在购买产品1时,起始页面是在webapp1中,一旦购买已经发生,我想回到webapp1中的页面,但只有webapp3具有刚刚完成购买的用户的详细信息在webapp1中显示在页面上。
这是出于安全原因,默认情况下不可能。 您需要首先配置Tomcat以启用将当前webapp的ServletContext
暴露给其他Web应用程序。 这可以通过将context.xml
的crossContext
属性设置为true
。
完成后,您可以使用ServletContext#getContext()
通过其上下文路径获取其他servlet上下文,最后使用ServletContext#getRequestDispatcher()
通常获得的RequestDispatcher
。
例如
ServletContext otherContext = getServletContext().getContext("/otherContext"); otherContext.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
是。
您需要做的第一件事是获取另一个webapp的ServletContext
。 您可以在自己的ServletContext
上使用ServletContext::getContext
执行此操作,并传递其他Web应用程序的上下文路径。
然后,您只需在外部上下文中执行ServletContext::getRequestDispatcher
。
我实际上没有试过这个,但我100%保证它会起作用。
我不确定不同的servlet容器。 但是它通过使用getServletContext()。getContext()方法适用于同一个容器。
首先,您需要在下面的文件中进行更改
(Windows)C:\ Program Files \ Apache Software Foundation \ Tomcat 7.0 \ conf \ context.xml将crossContext的值设置为true。
的context.xml
WEB-INF/web.xml
请注意, crossContext =“true” 。
假设您有两个Web应用程序,其名称为InterServletComm1 , InterServletComm2分别在每个Web应用程序中具有Servlet1和Servlet1 。 然后每个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("
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中接收。 如果答案不明确,请告诉我。