与 JAX-RS 混淆,Jersey 与 JAX-RS 混淆

Confusion with JAX-RS and Jersey with JAX-RS

我真的很困惑。我已经尝试了一个带有 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。

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

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

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

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

why jersey using a servlet?

我想上面说的很清楚了。

JAX-RS not using a servlet?

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

Why using JAX-RS, while we can use a just Servlet

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

[1] - 请参阅 2.3 Publication
[2] - 请参阅 3.7 Matching Requests to Resource Methods


更新

所以部分 OP 的部分混淆是,他正在学习的教程没有在 web.xml 文件中指定 Servlet,这让 OP 认为“vanilla JAX-RS”(不存在)被使用,不是一个实现。

JAX-RS 只是一个规范,如果没有实现就不能 运行。是的,有一个 javax.ws.rx-api.jarjavaee-api.jar 具有 classes/interfaces/annotations 到 编译 JAX-RS 应用程序,但没有实际的“引擎”在这个罐子里。实际的 JAX-RS“引擎”在特定的实现 jar 中。

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

另一个混淆点可能在应用程序配置中。不像在 OP 的 post 中那样使用 web.xml,而是使用 Application subclass。像

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

JAX-RS 规范指出,当此 class with annotation 可用时,应使用上述完全限定的 class 名称作为 Servlet 名称创建 Servlet,并且 url 映射为 @ApplicationPath 中的值。因此,无论您使用什么实现,这种行为都应该是相同的。

JAX-RS

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

为什么选择球衣?

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

备选方案

apache-cxf, which implements JAX-RS and does SOAP & REST both. I have been using jersey myself for years. Since I liked working with tomcat. Now we help built metamug,tomcat 上的框架,用于 XML 的 REST API。