JAX-RS和Jersey的混淆与JAX-RS有关。

5

我真的很困惑。我尝试使用Jax-rs和Tomcat,并使用所有的注释来通过url调用我的服务。所以没有Jax-rs,我可以简单地使用servlet并调用我的服务。此外,正如我所尝试过的,有Jax-rs带有jersey(据我研究是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呢?既然我们可以只使用Servlet,为什么要使用JAX-RS呢?

3个回答

9
JAX-RS规定了围绕Servlet的部署模型[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],反序列化实体主体和许多其他使所有魔法成为可能的东西。处理完后,它将响应发送回容器。

为什么Jersey使用Servlet?

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

JAX-RS不使用Servlet?

我不确定您在问什么,但JAX-RS规定了其他部署模型,但Servlet环境是唯一具有任何特定要求详细信息的选项。其他部署选项(如SE环境)将是实现特定的[1]

为什么要使用JAX-RS,而不直接使用Servlet?

您基本上在问:“当我可以实现自己的REST框架时,为什么要使用JAX-RS?”一般来说,如果有可用的框架,请使用它。如果您觉得可以做得更好,请自己动手做。

[1] - 请参阅2.3发布
[2] - 请参阅3.7匹配请求与资源方法


更新

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

JAX-RS仅是一个规范,没有实现就无法运行。确实有一个javax.ws.rx-api.jar或javaee-api.jar,其中包含编译JAX-RS应用程序所需的类/接口/注释,但该jar中没有实际的“引擎”。实际的JAX-RS“引擎”在特定的实现jar中。
我没有完整地观看教程,但我认为它使用了上述其中一个jar,这导致OP认为没有使用JAX-RS实现。但实际上,使用的Java EE服务器(即Glassfish)内部具有实现。在Glassfish的情况下,它是Jersey。
另一个混淆点可能在应用程序配置中。与OP的帖子中使用web.xml不同,使用了Application子类。类似于:
@ApplicationPath("/rest")
public class AppConfig extends Application {
    ...
}

JAX-RS规范指出,当使用该带有注解的类时,应该创建一个Servlet,其完整限定类名为Servlet名称,并且url映射应该是@ApplicationPath中的值。因此,无论您使用哪种实现,此行为应该是相同的。

非常感谢peeskillet,这让我消除了很多困惑。我还有一个疑问。所以我们可以使用JAX-RS来实现服务,对吗?我们不需要Jersey或任何其他JAX-RS实现。如果我错了,请纠正我。 - user3919392
JAX-RS只是一个规范,你需要实现它才能使用。没有JAX-RS实现就不存在使用JAX-RS的情况,比如Jersey、Resteasy、CXF等实现。 - Paul Samsotha
谢谢peeskillet。但是我看了下面的教程。我认为他没有使用任何Jersey、Resteasy或其他东西。只是注释。我错了吗?https://www.youtube.com/watch?v=-sPRp_ryyvY - user3919392
还有一种实现方式。您可以不使用web.xml,而是使用“Application”子类和“@ApplicationPath”注释。JAX-RS指定当它看到这个时,实现应该创建一个servlet。也许这就是您所指的。这些是唯一的两种部署方法。无论是web.xml还是“Application”子类。如果您要部署到Java EE兼容的服务器,则只需要java ee api jar即可。服务器将具有实现。JAX-RS是Java EE规范的一部分。 - Paul Samsotha
我明白了,非常感谢。 :) - user3919392
显示剩余2条评论

1

JAX-RS

JAX-RS是用于创建REST API的标准。你甚至可以构建一个像Jersey这样的库来实现这个标准。JAX-RS是JavaEE堆栈的一部分,就像JMS和其他组件一样。因此,像JBoss这样的应用服务器会预装jax-rs和jms。

为什么选择Jersey?

JAX-RS不会随Tomcat等一起预装。Jersey可以与Servlet容器(如Tomcat、Jetty等)一起使用。这类似于ApacheMQ,它可以让容器执行JMS。Jersey被设计为扩展Servlet以创建REST端点。它也是JAX-RS的一个实现。通过实现这个标准,它与为JAX-RS编写的代码保持一致。

其他选择

还有apache-cxf,它实现了JAX-RS,并支持SOAP和REST。我自己多年来一直在使用Jersey,因为我喜欢在Tomcat上工作。现在我们还帮助构建了metamug,这是一个基于Tomcat的用于处理带有XML的REST API的框架。


0

JAX-RS 定义了一些标准和规则。通常情况下,Jersey 是 JAX-RS 的实现。

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


虽然这是正确的,但它并不是一个完整的答案。 - Luiggi Mendoza
感谢Razib的回复。但这仍然没有解决我的困惑。那么Jax-RS不使用servlet吗?为什么Jersey在web.xml中指定了一个servlet? - user3919392

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接