Marc Hadley 和 Paul Sandoz 领导的 JSR-311 规范在 2008 年第一次发布 JAX-RS 1.0 时,它成为了最早的基于 POJO/ 注解的框架之一,这些框架致力于创建健壮的 Web 应用程序。
现在,五年的时间过去了,Java EE7 已经发布并且包含了最新的 JAX-RS 2.0 版本,它是 Marek Potociar 和 Santiago Pericas-Geertsen 领导的 JSR-339 实现。我们将看一下 JAX-RS 2.0 的一些关键特性,但首先让我们回顾一下 JAX-RS 1.0。
1 @Path(portfolios) 2 public class PortfolioResource { 3 4 @GET 5 public Collection<Portfolio> allPortfolios() { 6 . . . 7 } 8 9 @GET 10 public Portfolio getPortfolio( @PathParam("portfolioId") String id) { 11 . . . 12 } 13 }
在上面的代码列表中,第一行表明要将这个资源与相对路径“/portfolios”进行匹配。第四行表明 GET 请求将会返回所有的 portfolios。第九行和第十行表明像 /portfolios/123 这样的 URL 将会把资源 URL(如 portfolios)后面的参数抽取出来(如 123)并将它赋值给“id”变量,然后返回相关联的 portfolio。
在 JAX-RS 2.0 中保留了类似的语法。
JAX-RS 2.0 符合了 Java EE 7 的中心主题,添加了一些长久以来一直期待的特性,这些特性主要关注于 Oracle 所宣称的“简化的 API”。
这些特性可以列举如下:
- 客户端 API
- 异步
- HATEOAS(超媒体)
- 注解
- 校验
- 过滤器和处理器(Handler)
- 内容协商
我们会快速了解一下以上所列的每一项特性:
客户端 API
JAX-RS 1.0 是一个严格的服务端 API。有一些实现提供了不同程度的客户端支持,但是一般来讲开发人员需要安装专门的东西,像 Apache 软件基金会的 Jakarta Commons HttpClient 或者 WizTools 的 REST Client 。
JAX-RS 2.0 添加了“生成器(builder)”工具用于从客户端调用 Web 服务。以下为一个样例:
Client client=ClientFactory.newClient(); String shares=client.target("http://.../portfolio/123") .pathParam("identifier", "IBM") .queryParameter("identifierType", "ticker") .request("text/plain).get(String.class");
你可以看到这个方法首先获取了一个客户端,然后使用生成器模式(builder pattern)来构建 URL 的所有参数,这样的话就能让应用程序的开发人员格式化 URL,而不用处理构建 URL 的奇特行为。
对于调用带有 HTTP 体的请求,这种方式尤其有效,如 HTTP POST 以及 HTTP PUT。以下的样例可以卖出 IBM 的 100 股股票:
Stock stock=client.target("http://.../portfolio/123/sell") .pathParam("identifier", "IBM") .queryParameter("identifier", "ticker") .request("application/json") .post(text("100", Shares.class));
异步
在 JAX-RS 1.0 中,发起调用的客户端必须等待服务端的响应。2.0 引入了异步的支持。这样的话就允许客户端发起一个 RESTful 的请求,并得到一个 Future 或 an InvocationCallback,当响应完成的时候会获得通知。
HATEOAS(超媒体)
按照 REST 盲从者的正统(RESTafarian Orthodoxy),如果你没有使用 HATEOAS 的话,那你就不是在使用 REST!HATEOAS(Hypermedia as the Engine of Application State,超媒体作为应用程序状态引擎)需要 RESTful 的生产者和消费者在每次调用时返回一组达成共识的链接,它用于导航到下一个步骤。如果你将 REST 视为 Web 页面的应用版本,那么 HATEOAS 可以视为 Web 页面中的链接。
JAX-RS 2.0 提供了 Link 和 Target 类,它们用于服务器端在响应中引入超链接并在客户端对其进行响应。
注解
引入了新的注解,例如为了支持新注入的注解。
Bean 校验
会有一个基于注解的基础设施来指明元数据参数。例如“@NotNull shares”表明“shares”参数不能为 null。你还可以提供自定义的注解,例如保证一定的数据格式,像邮政编码或电话号码。
过滤器和处理器
Filter API 允许将 servlet 的过滤器放到一个链中,遵循责任链模式。如果要引入一些正交的关注点,如日志,那么它会很有用。任何的过滤器都可以继续或终止这个链,这是通过分别调用 FilterAction.NEXT 和 FilterAction.STOP 做到的。
处理器(handler)与过滤器很类似,但是它们会在一个特定的扩展点中包装方法调用。如果要拦截这个扩展点的调用,这种方式会很有用,例如要缓解或扩充负载数据。
内容协商
更为丰富的参数注解 @Accepts 和 @Produces 能够让你优先安排请求 / 响应的格式。
JAX-RS 依然缺乏很好的安全模型,对于面向外部的企业级应用程序就很难使用了。我们希望下一个释放版本能够提供点对点的认证。
主流的 JEE 容器可能还需要一些时间才能支持 JAX-RS 2.0。不过你可以将最新版本的 Jersey 与应用程序一起部署,这样就能使用这些特性了。Oracle 已经宣布了在WebLogic 12c 中做到这一点的步骤。
要了解更多的信息,请查看JSR 339 专家组成员Adam Bien 在OTN 上的文章 Java EE 7 and JAX-RS 2.0 。
评论