这篇文章中使用的示例代码可以在这里找到。
短暂休息
REST (表示状态转移)并不是什么新鲜事物,它是在2000年首次提出的(Fielding, 体系结构样式和基于网络的软件体系结构设计 ),但是今天它仍然未被充分利用,只是在最近几年才真正流行起来。 。 它用于通过URL描述资源,并允许操纵此类资源。 这个想法是利用HTTP协议在客户端和服务器之间创建一个与平台无关的,无状态的,缓存友好的接口。 尽管REST可以应用于其他协议,但目前我们仅关注HTTP。
用更简单的术语来说,诸如“ http://www.myserver.com/files/text.txt”之类的URL描述了一个资源,该资源是一个名为text.txt的文件,位于myserver.com域中。 那里什么都没有 您可以将浏览器指向该文件,浏览器将向服务器发送GET请求以获取该文件。 您甚至不需要编写任何应用程序就能做到这一点。 任何客户端和服务器都将以这种方式进行通信。
其他请求方法变得更加有趣。 每个阅读本文的人都应该熟悉POST方法(通常用于表单)。 在REST应用程序中,发布到URL表示您要编辑该URL上的资源。 不太常用的PUT和DELETE方法分别用于创建和删除资源。 例如,PUT http://www.myserver.com/files/text.txt应该创建一个文本文件,通常包含请求正文的内容。 值得注意的是,在某些系统中,尤其是那些旨在直接与浏览器进行交互的系统,出于某些目的,有时会劫持POST方法,因为某些浏览器对这两种方法的处理不太好。
REST还使用标头来控制缓存或确定客户端期望的内容类型或语言。 毕竟,一个请求是一个普通的旧HTTP请求。 这很不错,很干净,很灵活,并且不会为您提供与SOAP提供相同功能所需的大量管道服务。 在这一点上,我们使用它的原因应该很清楚。
静态资源类的解剖
尽管幕后有很多事情要做,但是Jersey很好地完成了将复杂性隐藏在漂亮的注解背后的工作。 考虑以下:
@Path("/people/{code}")public class Individual {@GET@Produces({"application/json", "application/xml"})public Object find(@PathParam("code") String code) { ... }@DELETEpublic void remove(@PathParam("code") String code) { ... }}
这是一个简单的类,可以根据唯一的代码查找或删除一个人的条目。 第一个批注“路径”指定该类(或方法–如果需要,您可以在方法级别覆盖路径)映射到哪个URL。 在这种情况下,我们要说的是,我们希望此类处理对“ [任何域] /人”的请求; 我们还将期望在“人员”之后有一个值,我们将其视为我们想要的人的唯一代码–就是括号中的值。
我们可以在路径中使用多个变量。 例如,我们可以说“ / team / {team_id} / {position}”或什至“ / team / {team_id} / staff / {position}”来获取填补团队中给定职位的人员的详细信息,取决于我们想要的详细程度。 我们还可以对参数施加限制; 例如,如果我们希望代码为数字值,则可以将其定义为“ {code:[0-9] *}”; 该定义接受正则表达式模式。
GET和DELETE批注指定哪个Java方法应该处理哪个HTTP方法。 这些方法还有POST和PUT批注。
PathParam批注从请求URL中获取参数,并将其传递给方法-在这种情况下,它将获取code参数。 到目前为止,不言自明 –甚至还有FormParam和HeaderParam版本可以分别从POST表单字段或请求标头中获取值。
我发现Produces注释非常有趣。 批注的参数采用MIME类型的集合,这些类型声明了该方法能够生成的返回类型。 在以上两种情况下,我们都可以提供JSON或XML响应-根据请求的ACCEPT标头的值选择要返回的响应-如果请求接受该方法提供的一种以上返回类型,则第一个返回最好在ACCEPT标头中列出。
归还任何东西
当返回用XmlRootElement注释的类的实例时,Jersey负责确定返回类型,并将该对象转换为所需的表示形式。 不用大惊小怪,不需要音乐。 如果您需要进行一些更高级的格式化(例如,转换为PDF或html页面),那么它应该与编写和注册给定类型的编组器一样简单,尽管我还没有深入研究。
用弹簧接线
当然,该资源类现在正处于适当的位置。 要将其放置在Web应用程序中,我们需要对其进行设置,而Spring将用于此目的。 忍受我 这不是很冗长,一次。
首先,我们需要告诉Spring我们的资源是可配置的组件。 为此,我们只需对类中的Component标注进行排序即可。 然后,我们需要定义范围; 由于REST是无状态的,因此我们将继续使用Scope批注(其值为“ request”)声明一个请求范围。 还没有惊喜! 现在,我们的类声明如下所示:
@Component@Scope("request")@Path("/people/{code}")public class Individual {...}
最后,只需告诉Spring在哪里寻找您的组件即可:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="your.namespace.here" /></beans>
–惊喜–注入注释以填充其字段。 仅此而已...您已经准备好要使用的REST资源。
并非全部
这就是全部。 除了我仍在研究的一些问题外-JAXB在找到循环参考时完全失去了大理石,使某些对象模型难以整理– JSR 311提供了一种将所有这些组合在一起的真正干净的方法。
有一个抱怨。 集合返回类型似乎是一个问题。 可以通过将集合包装在容器中来绕过此操作,但这似乎是不必要的步骤。
样品申请
该示例应用程序可以通过jQuery ajax调用从服务器上的内存映射中列出,加载或删除单个条目。 它已打包在两个WAR文件中(服务器和客户端)。 由于浏览器沙箱,请确保客户端程序包和服务器程序包都在同一域中; 如果您以编程方式连接到服务器,则不存在此限制。
我想我可能已经展示了POST或PUT的示例,但实际上,它足够简单,我真的很讨厌编写表单。
参考: JCG合作伙伴 提供的Jersey和Spring的RESTful Web应用程序 The Simple Part博客中的Karl Agius。
翻译自: https://www.javacodegeeks.com/2012/03/restful-web-applications-with-jersey.html