gpt4 book ai didi

java - session.getServletContext() 和 session.getServletContext().getContext 的区别 ("/SampleProject")

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:13:53 24 4
gpt4 key购买 nike

我有一个 Tomcat 6 实例在我的本地机器上运行。

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

  • 在/conf/context.xml – 如下更改标签

    <Context crossContext="true">
  • 在/conf/server.xml – 更改标签如下

    <Connector port="8080" protocol="HTTP/1.1" emptySessionPath="true"
    connectionTimeout="20000"
    redirectPort="8443" />

假设我在此处部署了一个名为 SampleProject.war 的 WAR 文件,该文件解压缩到文件夹 SampleProject

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

ServletContext context1 = session.getServletContext();

ServletContext context2 = session.getServletContext().getContext("/SampleProject");

context1context2 有什么区别?我认为两者都指的是应用程序上下文。但是如果我在 context1 中设置一些属性并在 context2 中访问,我不会在 context2 中获取值。

如有任何帮助,我们将不胜感激。

最佳答案

我觉得你的问题有点被误解了,你已经对 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邪恶 web 应用程序篡改。一旦“忘记密码”请求出现,您的应用程序可能会帮助妥协自身! :)

深入了解 Tomcat 内部结构

Tomcat 7 提供了一个 class ApplicationContext implements ServletContext,它从 getContext("/context-root") 返回为

    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 称它为 child ?

这两个实际上不是 ApplicationContext 而是 StandardContext 的实例 implements Context 但不是 servlet 特定的东西持有 Tomcat 特定的配置网络应用程序的设置,如 crossContext、主机名、mimeMappings 等。StandardContext.getParent() 为您提供 Container,因此它在上面被称为子项。

无论如何,我们对 child == context 为 true 的情况感兴趣,即 getContext() 在“/SameWebApp 上被调用”。该调用被委托(delegate)给 StandardContext.getServletContext(),它已被实现以返回 ApplicationContext不同实例

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

但是等等,还有更多。为什么 StandardContext.getServletContext() 返回类似

return (context.getFacade());

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

  • 提供容器,以及
  • 用户部署

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

Tomcat 为实现此目的所做的一件事是始终将 ApplicationContextFacade 包裹在 ApplicationContext 周围(因此也包裹 StandardContext) .因此,回顾一下,看似简单的 ServletContext 实现实际上是一个 StandardContext 映射到一个 ApplicationContext,然后将其包装在一个 ApplicationContextFacade.

有关 ApplicationContextFacade 如何将反射与 Globals.IS_SECURITY_ENABLEDSecurityUtil.isPackageProtectionEnabled() 设置结合使用的更多信息,请查看看Why do Servlets access Tomcat ApplicationContext through a Facade在 SO 上。

引用资料:
Tomcat 7 Source Code (Download Link)

关于java - session.getServletContext() 和 session.getServletContext().getContext 的区别 ("/SampleProject"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15639673/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com