规范:OSGi HTTP 白板和 ServletContextHelper

Specs: OSGi HTTP Whiteboard and ServletContextHelper

当多个包使用相同的 ServletContextHelper 时,我需要一些关于与 Http 白板规范相关的 ServletContextHelper 行为的精确信息

规范说:

The Http Whiteboard implementation must create a separate ServletContext instance for each ServletContextHelper service. Whiteboard services can be associated with the Servlet Context Helper by using the osgi.http.whiteboard.context.select property. If this property is not set, the default Servlet Context Helper is used.

如果我理解正确,所有使用相同 ServletContextHelper 引用的 Servlet 或 Filter 都绑定到相同的 'ServletContext'

然后:

Some implementations of the ServletContextHelper may be implemented using a Service Factory, for example to provide resources from the associated bundle, as the default implementation does. Therefore the Whiteboard implementation must get the Servlet Context Helper using the Bundle Context of the bundle that registered the Whiteboard service.

所以如果一个bundle A用ServletContextHelper X注册了一个Servlet,而bundle B用相同的ServletContextHelper引用注册了一个Filter,那么Servlet和Filter注册到同一个ServletContext,但是调用了它们的init方法使用两个不同的 ServletContext 实例(以便以不同方式实现 getClassLoader() 方法)?

此外,"default" ServletContextHelper 的行为是什么?是否总有一个 "default" ServletContextHelper 已注册?它是在捆绑包之间共享还是捆绑包只有一个实例?

我在 Pax Web 8 上工作,我真的很想在其中获得正确的行为。

140.2.7 Relation to the Servlet Container chapter of OSGi CMPN specification 显示了一张图片,其中实际上有三个 layers of javax.servlet.ServletContext objects:

  • ServletContext 特定于真实 Servlet 容器的实现。在 Pax Web 中,它是以下之一:
    • org.eclipse.jetty.servlet.ServletContextHandler.Context
    • org.apache.catalina.core.ApplicationContext
    • io.undertow.servlet.spec.ServletContextImpl
  • ServletContext 实现 1:1 与 org.osgi.service.http.context.ServletContextHelper OSGi 服务的关系
  • ServletContext 为每个 Whiteboard 包实现服务工厂合同,其中除 getClassLoader() 方法外的所有方法都委托给上述 SCH 和 getClassLoader() returns bundle.adapt(BundleWiring.class).getClassLoader()

这个问题与org.osgi.service.http.context.ServletContextHelper假设的双重责任原则有关。它用于实现功能方面 (handleSecurity()) 和资源分离方面 (getResource())。

所以你是对的 - 如果 Bundle A 注册一个 servlet 而 Bundle B 注册一个过滤器,两者将使用相同的 ServletContext 实例(由引用的 ServletContextHelper 支持),但它们的 init() 方法将是提供了 ServletContext.

的不同的特定于包的实例

这里只是简单的委托实现,有两种实现方式:

  • org.ops4j.pax.web.service.spi.servlet.OsgiServletContext 实现 1:1 行为
  • org.ops4j.pax.web.service.spi.servlet.OsgiScopedServletContext 实现 getClassLoader() 委托 上述所有其他方法 OsgiServletContext