在一个Servlet容器进程内可以同时运行多个Web应用,这些Web应用之间是可以进行通信的。前面我们已经学到,每个Web应用都有一个ServletContext大总管。对于Web应用A中的Servlet,只要得到了Web应用B的ServletContext对象,就可以访问到Web应用B的各种资源。
ServletContext接口中的getContext(String uripath)方法用于得到其他Web应用的ServletContext对象,参数uripath指定其他Web应用的URL入口。
一个Web应用随意访问另一个Web应用的各种资源,可能会导致安全问题。因此,为了安全起见,多数Servlet容器实现可以让用户设置是否允许Web应用得到其他Web应用的ServletContext对象。在Tomcat中,<Context>元素的crossContext属性用于设置该选项:
- 如果crossContext属性为false,那么<Context>元素对应的Web应用无法得到其他Web应用的ServletContext对象。当这个Web应用中的Servlet调用getContext(String uripath)方法时,该方法总是返回null。crossContext的属性默认为false.
- 如果crossContext属性为true,不那么<Context>元素对应的Web应用可以得到其他Web应用的ServletContext对象。当这个Web应用中的Servlet调用getContext()方法时,该方法返回参数uripath对应的其他Web应用的ServletContext对象。
下面这个例程的CrossServlet类的作用与上一节的CheckServlet类有些相似,不过CrossServlet没有把请求转发给当前Web应用的OutputServlet,而是转发给了helloapp1应用中的OutputServlet。
CrossServlet
import javax.servlet.*;
import java.io.IOException;
public class CrossServlet extends GenericServlet{
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException,IOException{
String username = servletRequest.getParameter("username");
String message = null;
if (username == null){
message = "Please input username.";
}else {
message = "Hi,"+username;
}
ServletContext context = getServletContext();
ServletContext crossContext = context.getContext("/helloapp1");
RequestDispatcher dispatcher = crossContext.getRequestDispatcher("/output");
dispatcher.forward(servletRequest,servletResponse);
}
}
然后,将web.xml文件中的CrossServlet映射配置好。在web/META-INF目录下创建用于配置<Context>元素的context.xml文件,内容如下:
<Context reloadable="true" crossContext="true"/>
下面,部署一个新的Web应用,helloapp1,配置好OutputServlet的URL映射。然后运行原来的应用,我们的CrossServlet就会把请求转发给helloapp1中的OutputServlet,最后由OutputServlet返回响应结果。