我觉得你的问题有点被误解了,你已经对 API 有了基本的了解,即一旦网络应用程序设置了crossContext="true"
它,它就可以getContext()
用来访问与服务器上部署的其他一些网络应用程序相对应的上下文。
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
. 一旦“忘记密码”请求出现,您的应用程序可能会帮助自己妥协!:)
深入了解 Tomcat 内部结构
Tomcat 7 提供了一个class ApplicationContext implements ServletContext
从getContext("/context-root")
as返回的
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
属于当前的 web-app,child
代表另一个 web-app。但是,等等,是什么让 Tomcat 称它为孩子?
这两个实际上不是一个类的ApplicationContext
实例,它不是 servlet 特定的东西,而是为 web 应用程序(如 crossContext、主机名、mimeMappings 等)保存 Tomcat 特定的配置设置,因此它被称为上面的子级.StandardContext
implements Context
StandardContext.getParent()
Container
无论如何,我们感兴趣的情况是什么时候child == context
为真,即getContext()
在“/ SameWebApp ”上被调用。该调用被委派给StandardContext.getServletContext()
已实现返回不同实例的ApplicationContext
.
这就是为什么你设置的属性context1
在context2
.
但是等等,还有更多。为什么StandardContext.getServletContext()
返回喜欢
return (context.getFacade());
一个 Tomcat 实例基本上执行两种类型的 Java 代码:
容器代码是“受信任的”,有时可能需要以提升的权限运行。另一方面,用户代码不受信任,需要限制其破坏 Tomcat 内部。
Tomcat 为实现这一目标所做的其中一件事就是始终环绕ApplicationContextFacade
(ApplicationContext
因此也是StandardContext
如此)。因此,回顾一下,看似简单的ServletContext
实现实际上是StandardContext
映射到 anApplicationContext
然后包装在ApplicationContextFacade
.
有关如何将ApplicationContextFacade
反射Globals.IS_SECURITY_ENABLED
与SecurityUtil.isPackageProtectionEnabled()
设置结合使用的更多信息,请查看为什么 Servlet 通过SO 上的 Facade 访问 Tomcat ApplicationContext。
参考:
Tomcat 7 源代码(下载链接)