我知道这个问题有很多答案,但我仍然对JAX-RS API(规范)和Jersey框架(参考实现)之间的区别感到困惑 .
我读到了:
Jersey框架基本上使用com.sun.jersey.spi.container.servlet.ServletContainer servlet来拦截所有传入的请求 . 正如我们在项目web.xml中配置的那样,所有传入的rest请求都应由该servlet处理 . 有一个init-param配置了jersey servlet来查找REST服务类 . REST服务类不是Servlet,它们不需要像在代码中那样扩展HttpServlet . 这些REST服务类是简单的POJO注释,用于告诉jersey框架不同的属性,如路径,消耗,产生等 . 当您从服务方法返回时,jersey负责在定义的'PRODUCES'responseType中编组这些对象并编写它在客户端流上
我的问题是当你说:“泽西负责在定义的'PRODUCES'responseType中编组那些对象并将其写在客户端流上”,你的意思是泽西,什么是处理对象的实际类或库 .
当我读到泽西是处理JAX-RS API规范的引擎时,我很困惑 . 有人可以解释一下这句话中汗衫背后究竟是什么?来自 Jersey 的实际 class 在 Jersey 处理请求和回复的工作?
2 回答
规范和实现的概念实际上是非常基本的软件工程概念 . 您的规格是高级设计 . 为了帮助理解,我想出了一个非常简单的例子 .
说我想要一个解析库 . 我知道我希望如何使用它 . 唯一的问题是我不擅长编写解析代码 . 所以我创建了一个高级规范,并将实现外包出去 . 以下是作为规范一部分的三个类 . 它们都包含在一个"API jar"中,比如 myparsers-api.jar
所以在这一点上,我实际上可以对这个jar进行编码 . 如果我现在在另一个项目中使用它,该项目将编译得很好 .
因此,即使没有实现此规范,我仍然可以对其进行编码,并针对它进行编译 . 但是当我尝试实际运行该程序时,它将无法工作,因为没有实现 . 您可以尝试运行此代码,您将获得
IllegalStateException
(如果您不熟悉此模式,请参阅the docs for ServiceLoader) .所以我将实现外包给一家名为Stack Overflow的公司 . 他们得到我的myparsers-api.jar,他们需要给我一个实现 . 他们需要实现一个
ParserFactory
和几个Parser
. 他们可能看起来像这样现在,Stack Overflow给了我一个jar(比如说 so-myparsers-impl.jar )这三个类和所需的META-INF / services文件(按照ServiceLoader模式),现在当我将so-myparsers-impl.jar添加到我的项目中时尝试再次运行它,该程序现在可以工作,因为现在它有一个实现 .
这正是JAX-RS规范的工作原理 . 它只定义了它应该如何工作的高级设计 . 作为该设计一部分的类,接口和注释放在_2698334中,就像我的高级解析器被放入jar中一样 . 实现不能改变这些类 . 所有属于JAX-RS规范(版本2.x)的类都放在一个jar javax.ws.rs-api中 . 你可以针对那个jar进行编码,你的代码就可以编译得很好 . 但没有什么可以做到的"work" .
您查看了the written specification和classes defined by the specification,您会注意到源代码中包含的唯一类是规范中提到的类 . 但是你应该注意的是,书面规范没有提到任何关于它应该如何实现的内容 . 以下面的代码为例
现在规范声明这就是我们在servlet容器中运行JAX-RS应用程序所需的全部内容 . 这就是它所说的 . 它没有说明它应该如何工作 . 这就是它的设计工作方式 .
那么,Java中有一些神奇的巫术,我们不知道这将使这个
Application
类启动一个服务器,并且一些hocus pocus会使一个@Path
带注释的类自动接受请求 . 没有 . 有些身体需要提供引擎 . 引擎可能是20,000行代码,只是为了使上面的代码按指定的方式工作 .话虽这么说, Jersey 只是一个实施的名称 . 这就像我将解析器实现外包给Stack Overflow;名称Jersey本身就是项目的名称,就像Hadoop是项目的名称一样 . 在这种情况下,项目是JAX-RS规范的实现 . 而且因为JAX-RS只是一个规范,所以任何人都可以实现它 . 如果你愿意,你可以编写自己的实现 . 只要它的工作方式如何定义为在书面规范中工作,那么您可以说您的代码是JAX-RS的实现 . 那里不仅仅是 Jersey ;你也有RESTEasy,这是另一个实现 .
至于 Jersey 如何实施引擎,这太过广泛了 . 我能做的是,让您高度了解幕后发生的事情 .
JAX-RS应用程序定义为在servlet容器内运行 . 如果您了解servlet容器和servlet规范,那么您将知道处理请求的唯一方法是编写
HttpServlet
或Filter
. 因此,如果要实现JAX-RS,则需要能够通过HttpServlet
或Filter
处理请求 . 你提到的ServletContainer实际上都是 . 所以对于Jersey来说,这是关于Jersey应用程序的"entry point",就请求处理而言 . 它可以通过多种方式配置(我将这项研究留给您) .如果您了解如何编写自己的servlet,那么您知道所有获得的是
HttpServletRequest
和HttpServletResponse
. 你需要弄清楚从那里做什么;从请求中获取请求信息,并在响应中发回响应信息 . 泽西处理所有这些 .如果你真的想深入了解幕后内容的细节,你只需要从入口点
ServletContainer
开始深入挖掘源代码 . 准备好花几个月时间来了解这一切是如何运作的 . 它's not something that can be explained in one Stack Overflow post, if that'是你所期待的 .你已经指出JAX-RS是 specification 而Jersey是 implementation 这是Java如何特别是Java EE工作,也许这可以更好地解释.2698355_ .
总结一下JAX-RS只是一个规范,没有真正的实现 . 真正的实现是由Jersey和其他遵循JAX-RS规范的库完成的 .