【问题标题】:Confusion with JAX-RS and Jersey with JAX-RS混淆 JAX-RS 和 Jersey 与 JAX-RS
【发布时间】:2015-03-19 16:10:33
【问题描述】:

我真的很困惑。我已经尝试了一个带有 tomcat 的 Jax-rs,并使用了我能够使用 url 调用我的服务的所有注释。因此,如果没有 Jax-rs,我可以简单地拥有一个 servlet 并调用我的服务。同样,正如我所尝试的那样,有带有球衣的 jax-rs(因为我研究了它的 JAX-RS 的实现),并且在 web.xml 中有以下内容。

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>OutputUi</display-name>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>org.xxx.carbon.servlet</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

然后我有与 JAX-RS 相同的注释,在 GET 上我可以使用正确的 URL 调用我的服务。

我的问题是,为什么 jersey 使用 servlet? JAX-RS 不使用 servlet 吗?为什么要使用JAX-RS,而我们可以只使用一个Servlet。

【问题讨论】:

    标签: java servlets jersey jax-rs


    【解决方案1】:

    JAX-RS 指定围绕 Servlets[1] 的部署模型。为什么,因为在 Java 世界中,这就是 Web 应用程序的运行方式。请求进入 Servlet 容器(如 Tomcat 或完整 Java EE 服务器中的容器),容器将请求交给 Servlet 应用程序,应用程序处理请求并将响应返回给容器,容器将其发送给客户。 Spring MVC 是一个基于 Servlet 的框架(主 Servlet 为 DispatcherServlet)。 JSF 是一个基于 Servlet 的框架(主要的 Servlet 是FacesServlet)。围绕 Servlet 构建 JAX-RS 的方式相同(主 Servlet 是特定于实现的;在 Jersey 的情况下是 ServletContainer)。

    Request 进入 Tomcat,它查找 servlet 映射,发现 ServletContainer 与请求 URL 匹配,它将请求包装在 HttpServletRequest 中并将其发送到 Jersey Servlet。现在 Jersey 可以随心所欲地处理它,这是一个很大的处理过程;例如处理请求以匹配您的方法[2]、反序列化实体主体以及一大堆其他使所有魔法成为可能的东西。完成处理后,它会将响应发送回容器。

    为什么 jersey 使用 servlet?

    我认为上面已经说得很清楚了。

    JAX-RS 不使用 servlet?

    不太确定我是否真的理解您的要求,但 JAX-RS 指定了其他部署模型,但 Servlet 环境是唯一具有任何特定要求细节的环境。其他部署选项(例如在 SE 环境中)将是特定于实施的[1]

    为什么要使用 JAX-RS,而我们可以只使用 Servlet

    您基本上是在问,“当我可以实现自己的 REST 框架时,为什么还要使用 JAX-RS?”。通常,当有可用的框架时,使用它。如果你觉得你可以做得更好,那就去做吧。

    [1] - 见2.3 Publication
    [2] - 见3.7 Matching Requests to Resource Methods


    更新

    因此,部分 OP 的部分困惑是,他正在阅读的教程没有在 web.xml 文件中指定一个 Servlet,这使得 OP 认为“vanilla JAX-RS” (不存在)正在使用,ant不是实现。

    JAX-RS 只是一个规范,没有实现就无法运行。是的,有一个 javax.ws.rx-api.jarjavaee-api.jar 具有用于编译 JAX-RS 应用程序的类/接口/注释,但这个 jar 中没有实际的“引擎”。实际的 JAX-RS“引擎”在具体的实现 jars 中。

    我没有看过完整的教程,但我认为它使用了上述 jar 之一,这导致 OP 相信没有使用 JAX-RS 实现。但实际上,使用的 Java EE 服务器(即 Glassfish)在内部具有实现。对于 Glassfish,它是泽西岛。

    另一个混淆点可能是应用配置。不是像在 OP 的帖子中那样使用 web.xml,而是使用了一个 Application 子类。类似的东西

    @ApplicationPath("/rest")
    public class AppConfig extends Application {
        ...
    }
    

    JAX-RS 规范规定,当这个带有注解的类可用时,应创建一个 Servlet,并使用上述完全限定的类名作为 Servlet 名称,并且映射的 url 为 @ApplicationPath 中的值。所以无论你使用什么实现,这个行为应该是一样的。

    【讨论】:

    • 非常感谢 peeskillet 这让我的很多困惑变得清晰。我还有另一个澄清。那么我们可以使用 JAX-RS 来实现服务吗?我们不需要 Jersey 或任何其他 JAX-RS 实现。如果我错了,请纠正我
    • JAX-RS 只是一个规范。您需要一个实现来使用它。没有像 Jersey、Resteasy、CXF 这样的 JAX-RS 实现,就没有使用 JAX-RS 之类的东西
    • 谢谢peeskillet.. 但我看了下面的教程。我认为他没有使用任何 Jersey、Resteasy 或任何东西。只是注释。我在这里错了吗? youtube.com/watch?v=-sPRp_ryyvY
    • 还有一个实现。您可以不使用 web.xml,只需使用 Application 子类和 @ApplicationPath 注释。 JAX-RS 指定实现应该在看到这个时创建一个 servlet。也许这就是你所指的。这是仅有的两种部署方法。 web.xml 或Application 子类。如果要部署到符合 Java EE 的服务器,则只需要 java ee api jar。服务器将有实现。 JAX-RS 是 Java EE 规范的一部分
    • 我明白了.. 非常感谢。 :)
    【解决方案2】:

    JAX-RS

    JAX-RS 是创建 REST API 的标准。甚至您也可以构建像 jersey 这样的库来构建标准的实现。 JAX-RS 是 JavaEE 堆栈的一部分,如 JMS 和其他。因此,像 JBoss 这样的应用程序服务器与 jax-rs 和 jms 捆绑在一起。

    为什么选择泽西岛?

    JAX-RS 没有与 tomcat 捆绑在一起。 Jersey 可以与 Tomcat、Jetty 等 servlet 容器一起使用。这类似于 ApacheMQ,它可以使容器执行 JMS。它旨在扩展 servlet 以创建休息端点。它也是 JAX-RS 的一种实现。实施该标准使其与为 JAX-RS 编写的代码保持一致。

    替代品

    apache-cxf,它实现了 JAX-RS 并同时执行 SOAP 和 REST。我自己多年来一直在使用球衣。因为我喜欢使用 tomcat。现在,我们帮助构建了metamug,这是一个在 tomcat 上用于带有 XML 的 REST API 的框架。

    【讨论】:

      【解决方案3】:

      JAX-RS 定义了一些标准和规则。一般来说,Jersey 是一个 JAX-RS 实现。

      但更具体地说,Jersey 是一个比 JAX-RS 参考实现更多的框架。 Jersey 提供了自己的 API,通过附加功能和实用程序扩展了 JAX-RS 工具包,以进一步简化 RESTful 服务和客户端开发。

      【讨论】:

      • 虽然这是真的,但它不是一个完整的答案。
      • 感谢 Razib 的回复。但这仍然不能解决我的困惑。那么 Jax-RS 不使用 servlet 吗?为什么 jersey 在 web.xml 中指定了一个 servlet?