【问题标题】:Servlet 3.0 and JAX-RSServlet 3.0 和 JAX-RS
【发布时间】:2016-01-22 01:48:07
【问题描述】:

我发现此问题的答案相互矛盾,但未能成功运行示例。

可以只使用带有注释的 Servlet 3.0(特别是 Tomcat 7)来实现 JAX-RS,而不必实现另一个 Servlet 容器吗?

如果不是,请解释为什么本书中的以下引用不正确或我在解释它是错误的。

因为此示例部署在 Java EE 应用服务器或 独立的 Servlet 3.x 容器,我们只需要一个空的 web.xml 文件。服务器将检测到 Application 类在您的 WAR 并自动部署它。 (带有 JAX-RS 2.0 的 RESTful Java,Bill Burke)

为了澄清我不需要需要帮助...我已经成功地使用 web.xml 在带有 Jersey 的 Tomcat 7 中实现了 JAX-RS,所以,我不需要任何解释如何这样做。此外,我完全了解其他 Java EE/Servlet 容器(TomEE、Glassfish、Jersey、Websphere 等)都是开箱即用的 JAX-RS。我只需要知道我是否在试图让 Tomcat 7 (Servlet 3.0) 在不添加 Servlet 容器和 web.xml 条目的情况下与 JAX-RS 一起工作。

【问题讨论】:

    标签: jax-rs


    【解决方案1】:

    在 Servlet 环境中,Jersey 作为 servlet 或 servlet 过滤器运行。没办法。那么不在 web.xml 中声明它是如何工作的呢?此功能的两个主要组件

    • Servlet 组件(即 Servlet 和过滤器)的编程注册。你可以用谷歌搜索,你应该会找到一些例子。

    • Servlet 3.x 中引入的 Servlet 可插入性。它的工作原理是实现一个ServletContainerInitializer,将该实现列在一个名为javax.servlet.ServletContainerInitializer 的文件中,然后将该文件放在jar 的META-INF/services 目录中。 servlet 容器应该扫描 jar 以查找此文件。当它找到时,它会看到实现,找到实现,实例化它,然后调用它onStartup 方法。

      Jersey 在JerseyServletContainerInitializer 中有这样一个SevletContainerInitializer 的实现。这个类位于jersey-container-servlet jar 中。所以你需要这个罐子才能工作。如果您查看this method,您将在此处看到ServletContainer 的编程注册(与您在web.xml 中声明的相同

    但这还不是全部。我们仍然需要某种方式来配置我们的应用程序,至少声明 servlet 映射。这就是Application 类和@ApplicationPath 注释出现的地方。我们将扩展Application 类并注释@ApplicationPath("/path"),其中"path" 与web.xml 中的servlet 映射相同

    @ApplicationPath("/api")
    public class MyApplication extends Application {}
    

    这是标准的 JAX-RS。通常使用 Jersey 而不是 Application 类,我们使用 ResourceConfig 类(它是 Application 的子类)

    @ApplicationPath("/api")
    public class MyApplication extends ResourceConfig {
        public MyApplication() {
            packages("package.to.scan");
        }
    }
    

    您可以在 Servlet 3.x 环境中查看有关 Jersey 部署选项的更多信息,here。

    还应注意,Java EE 服务器具有 JAX-RS 实现,因此我们只需将 javaee-api jar 作为提供的依赖项添加到我们的应用程序中。但是在 servlet 容器中,我们需要提供自己的实现,Jersey 就是这样的实现。

    如果你使用 Maven,你需要的主要依赖就是这个

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey2.version}</version>
    </dependency>
    

    这会拉入一堆其他的 jars。如果你没有使用 Maven,那么你可以下载所有的 jars here (the JAX-RS 2.0 RI bundle),然后将它们全部放入你的应用程序中。

    另请参阅:

    【讨论】:

    • 感谢您的宝贵时间。我想知道是否可以在没有 Jersey 或 web.xml 条目的情况下将其部署在 Tomcat 7 (Servlet 3.0) 中。一些参考资料说,让 JAX-RS 工作所需的只是 JavaEE 或 Servlet 3.0.... 没有提及 Servlet 容器/初始化器(除了 javax.ws.rs.core.Application)。如果 Servlet 3.0 中仍然需要 servlet 容器/初始化器,那么我读过的书和参考资料是错误的。你确定你不是指 Servlet 3.0 之前的 Tomcat?
    • 不,你不能没有 JAX-RS 实现。只有 Java EE 服务器配备了 JAX-RS。 Tomcat没有。 JAX-RS 是 Java EE 规范的一部分。 Tomcat 不是符合 EE 的服务器。它仅支持部分规范,如 servlet 和 jsp。规范的其他特性,我们需要自己添加,比如JAX-RS(它本身只是一个规范)通过添加它的实现(比如Jersey或者RESTeasy)
    • 好的。因此,在我所指的书中的示例中,只有一个扩展 javax.ws.rs.core.Application 的类,并且附加了资源类。只有一个空白的 web.xml 并且没有包含 servlet 容器(即 Jersey)。以下文本如我在上面引用的那样:“因为这个示例部署在 Java EE 应用程序服务器或独立的 Servlet 3.x 容器中,我们只需要一个空的 web.xml 文件。服务器将检测到 Application 类在您的 WAR 并自动部署它。”根据你的说法,这本书是错的?
    • 查看示例项目中的依赖项。它可能包含一个 RESTeasy 依赖项。本书的作者是 RESTeasy 的创建者,它是一个 JAX-RS 实现。如果该示例具有 resteasy-servlet-initializer 依赖项,则该示例将起作用的唯一方法。如果不是,它将无法在 Tomcat 中运行。该依赖项包含 RESTeasy 对 ServletContainerInitializer 的实现
    • 您将需要 Maven 来运行示例。如果不了解 Maven,那么您将无法运行这些示例。所有依赖项都是pom.xml 文件。当您使用 Maven 构建项目时,Maven 会拉入所有 jar。我现在正在查看示例项目,是的,它们确实包含 RESTeasy 作为 pom.xml 文件中的依赖项。这就是示例使用的 JAX-RS 实现
    猜你喜欢
    • 2016-05-07
    • 1970-01-01
    • 2015-01-25
    • 2016-12-02
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    相关资源
    最近更新 更多