我觉得您的问题有点被误解了,并且您已经对 API 有了基本的了解,即一旦网络应用设置其 crossContext="true",它就可以使用 getContext() 来访问与其他网络相对应的上下文-app 部署在服务器上。
getServletContext().getContext() equals NULL unless <Context crossContext="true">
据我了解,您的问题实际上是/SameWebApp 为什么
ServletContext context1 = session.getServletContext();
context1.setAttribute("contextAttribute", new Object());
ServletContext context2 = session.getServletContext().getContext("/SameWebApp");
System.out.println(context1.equals(context2)); // prints false, or
System.out.println(context2.getAttribute("contextAttribute")); // prints null (at least they could have been clones)
一句话,答案就是“安全”。想象一下,如果您不能保证“adminEmail”上下文属性没有被具有crossContext=true 的evil web 应用程序篡改。一旦“忘记密码”请求出现,您的应用程序可能会帮助自己妥协! :)
深入了解 Tomcat 内部
Tomcat 7 提供了一个从getContext("/context-root") 返回的class ApplicationContext implements ServletContext
if (context.getCrossContext()) {
// If crossContext is enabled, can always return the context
return child.getServletContext();
} else if (child == context) {
// Can still return the current context
return context.getServletContext();
} else {
// Nothing to return
return (null);
}
这里context 属于当前网络应用,child 代表另一个网络应用。但是,等等,是什么让 Tomcat 称它为孩子?
这两个实际上不是ApplicationContext,而是StandardContext 的实例@ 987654336@ 的类,但不是servlet 特定的东西,而是为Web 应用程序保存Tomcat 特定的配置设置,如crossContext、主机名、mimeMappings 等。@987654337 @ 给你Container,因此在上面它被称为一个孩子。
无论如何,我们对child == context 为真的情况感兴趣,即getContext() 在“/SameWebApp”上被调用。调用被委派给StandardContext.getServletContext(),该调用已实现返回ApplicationContext 的不同实例。
这就是您在context1 中设置的属性在context2 中找不到的原因。
但是等等,还有更多。为什么StandardContext.getServletContext()返回like
return (context.getFacade());
一个 Tomcat 实例基本上是在执行两种 Java 代码:
容器代码是“受信任的”,有时可能需要以提升的权限运行。另一方面,用户代码不受信任,需要限制其破坏 Tomcat 内部。
Tomcat 为实现这一目标所做的其中一件事是始终将ApplicationContextFacade 包裹在ApplicationContext 周围(因此也将StandardContext 包裹起来)。回顾一下,看似简单的ServletContext 实现实际上是一个StandardContext 映射到一个ApplicationContext,然后包装在一个ApplicationContextFacade 中。
有关ApplicationContextFacade 如何将反射与Globals.IS_SECURITY_ENABLED 和SecurityUtil.isPackageProtectionEnabled() 设置结合使用的更多信息,请查看SO 上的Why do Servlets access Tomcat ApplicationContext through a Facade。
参考:
Tomcat 7 Source Code (Download Link)