session.getServletContext()和session.getServletContext()之间的区别.getContext("/ SampleProject")

Tec*_*und 7 java tomcat servlets

我在本地计算机上运行了Tomcat 6实例.

我在其配置中进行了以下更改:

假设我有一个名为SampleProject.wardeploy 的WAR文件,它提取到文件夹SampleProject.

在这个WAR中的一些servlet中,比方说SampleServlet,我写了两段代码,如下所示:

ServletContext context1 = session.getServletContext();
Run Code Online (Sandbox Code Playgroud)

ServletContext context2 = session.getServletContext().getContext("/SampleProject");
Run Code Online (Sandbox Code Playgroud)

context1和之间有什么区别context2?我认为两者都是指应用程序上下文.但是,如果我设置了一些属性context1并访问context2,我没有得到的价值context2.

任何帮助,将不胜感激.

Rav*_*yal 5

我觉得你的问题有点被误解了,你已经对API有了基本的了解,即一旦web-app设置了crossContext="true"它就可以用它getContext()来访问与服务器上部署的其他web-app相对应的上下文.

getServletContext().getContext() equals NULL unless <Context crossContext="true">
Run Code Online (Sandbox Code Playgroud)

从我的理解,你的问题实际上是/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)
Run Code Online (Sandbox Code Playgroud)

只用一个词,答案是"安全".想象一下,如果你不能保证"adminEmail"上下文属性没有被具有它的邪恶网络应用程序篡改crossContext=true.一旦"忘记密码"请求到来,您的应用程序可能会帮助自己妥协!:)

潜入Tomcat内部

Tomcat 7提供了一个class ApplicationContext implements ServletContextgetContext("/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);
    }
Run Code Online (Sandbox Code Playgroud)

这里context属于当前的网络应用程序,child代表其他网络应用程序.但是,坚持一下,是什么让Tomcat称之为小孩?

这两个实际上不是一个类的ApplicationContext实例StandardContext,implements Context但是而不是servlet特定的东西保持Tomcat特定的配置设置为web-app如crossContext,hostname,mimeMappings等StandardContext.getParent()给你Container,因此它被称为上面的孩子.

无论如何,我们对child == context真实情况感兴趣,即getContext()在"/ SameWebApp " 上调用.该呼叫被委托给StandardContext.getServletContext()已实施,以返回不同的实例ApplicationContext.

这就是为什么context1找不到您设置的属性的原因context2.

但是等等,还有更多的东西.为什么StandardContext.getServletContext()回归就好

return (context.getFacade());
Run Code Online (Sandbox Code Playgroud)

Tomcat实例基本上执行两种类型的Java代码:

  • 容器提供,和
  • 用户已部署

容器代码是"受信任的",有时可能需要使用提升的权限运行.另一方面,用户代码不受信任,需要限制其破坏Tomcat内部.

其中一个是Tomcat的确实实现这一目标始终是一个包装的东西ApplicationContextFacade周围的ApplicationContext(因而StandardContext也).所以回顾一下,似乎是一个简单的ServletContext实现实际上是StandardContext映射到一个ApplicationContext然后包装在一个ApplicationContextFacade.

有关如何ApplicationContextFacade使用Reflection Globals.IS_SECURITY_ENABLEDSecurityUtil.isPackageProtectionEnabled()设置和设置协同工作的更多信息,请查看为什么Servlet通过 SO上的Facade访问Tomcat ApplicationContext.

参考文献:
Tomcat 7源代码(下载链接)