Jersey 是如何连接到 servlet 3 容器的

how is Jersey hooked up to servlet 3 container

对于 servlet 2.5,必须在 web.xml 中声明 Jersey 容器 servlet 才能将 Jersey 连接到 Tomcat。

<web-app>
    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            ...
        </init-param>
    </servlet>
</web-app>

对于servlet 3.x,我们可以做同样的事情。但是我们也可以去掉web.xml中的Jersey容器servlet,直接放一个Application subclass进去。

<web-app>
    <servlet>
        <servlet-name>org.foo.rest.MyApplication</servlet-name>
    </servlet>
    ...
    <servlet-mapping>
        <servlet-name>org.foo.rest.MyApplication</servlet-name>
        <url-pattern>/resources</url-pattern>
    </servlet-mapping>
    ...
</web-app>

我的问题是,在这种情况下,Jersey 是如何集成到 Tomcat 中的? Application class 是隐含地做某事,还是 servlet 自动发现 class 路径中的 Jersey jar?

我不确定 jersey 是如何实现它的,但他们可能使用了几种方法:

  • 在 Servlet 3.0 (http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html) 中引入了一个名为 ServletContainerInitializer 的特性,它允许 library/runtime 被通知 Web 应用程序的启动阶段并执行任何需要的 servlet、过滤器和侦听器的编程注册以响应它

  • 可以将他的库创建为 web-fragment,这样您就可以在 jar 中拥有 web-fragment.xml,您可以在其中注册 servlets/filter/etc。然后在启动期间此 web-fragment.xmlweb.xml 合并。因此,在 Web 片段中注册的组件被视为在 web.xml

  • 中注册

编辑:(来自@peeskillet 评论)Jersey 使用 servlet 容器初始化器:https://github.com/jersey/jersey/blob/master/containers/jersey-servlet/src/main/java/org/glassfish/jersey/servlet/init/JerseyServletContainerInitializer.java