7.3 使用 REST 服务

您是否曾经去看电影,当电影开始的时候,您发现只有您一个人在电影院?从本质上说,这是一次私人观影的美妙经历。您可以选择任何您想要的座位,和屏幕上的人物交谈,甚至可以打开您的手机发推特谈论它,而不会有人因为破坏了他们的观影体验而生气。最棒的是,也没有其他人会为您毁了这部电影!

这种情况在我身上并不常见。但当它出现的时候,我在想如果我没有出现会发生什么。他们还会放映这部电影吗?英雄还会拯救世界吗?电影结束后,工作人员还会打扫影院吗?

没有观众的电影就像没有客户端的 API。它已经准备好接受和提供数据了,但是如果 API 从未被调用过,那么它真的是一个 API 吗?就像薛定谔的猫一样,在我们向它发出请求之前,我们无法知道 API 是活动的还是返回 HTTP 404 响应。

Spring 应用程序既提供 API,又向另一个应用程序的 API 发出请求,这种情况并不少见。事实上,在微服务的世界里,这正变得越来越普遍。因此,花点时间看看如何使用 Spring 与 REST API 交互是值得的。

Spring 应用程序可以通过以下方式使用 REST API:

  • RestTemplate —— 一个由 Spring 核心框架提供的简单、同步 REST 客户端。
  • Traverson —— 可感知超链接的同步 REST 客户端,由 Spring HATEOAS 提供,灵感来自同名的 JavaScript 库。
  • WebClient —— 一个响应式、异步 REST 客户端。

现在,我们将主要关注 RestTemplate。在第 12 章讨论 Spring 的响应式 web 框架之前,我将推迟讨论 WebClient。如果您有兴趣 编写支持超链接的客户端,请查看以下位置的 Traverson 文档:https://docs.spring.io/spring-hateoas/docs/current/reference/html/#client

从客户的角度来看,与 REST 资源进行交互需要做很多工作 —— 主要是单调乏味的样板文件。使用低级 HTTP 库,客户端需要创建一个客户端实例和一个请求对象,执行请求,解释响应,将响应映射到域对象,并处理过程中可能抛出的任何异常。不管发送什么 HTTP 请求,所有这些样板文件都会重复。

为了避免这样的样板代码,Spring 提供了 RestTemplate。正如 JDBCTemplate 处理使用 JDBC 糟糕的那部分一样,RestTemplate 使你不必为调用 REST 资源而做单调的工作。

RestTemplate 提供了 41 个与 REST 资源交互的方法。与其检查它提供的所有方法,不如只考虑 12 个惟一的操作,每个操作都有重载,以形成 41 个方法的完整集合。表 7.2 描述了 12 种操作。

表 7.2 RestTemplate 定义的 12 个唯一操作,每一个都重载了,共提供41种方法(未完待续)

方法 描述
delete(...) 对指定 URL 上的资源执行 HTTP DELETE请求
exchange(...) 对 URL 执行指定的 HTTP 方法,返回一个 ResponseEntity,其中包含从响应体映射的对象
execute(...) 对 URL 执行指定的 HTTP 方法,返回一个映射到响应体的对象
getForEntity(...) 发送 HTTP GET 请求,返回一个 ResponseEntity,其中包含从响应体映射的对象
getForObject(...) 发送 HTTP GET 请求,返回一个映射到响应体的对象
headForHeaders(...) 发送 HTTP HEAD 请求,返回指定资源 URL 的 HTTP 请求头
optionsForAllow(...) 发送 HTTP OPTIONS 请求,返回指定 URL 的 Allow 头信息
patchForObject(...) 发送 HTTP PATCH 请求,返回从响应主体映射的结果对象
postForEntity(...) 将数据 POST 到一个 URL,返回一个 ResponseEntity,其中包含从响应体映射而来的对象
postForLocation(...) 将数据 POST 到一个 URL,返回新创建资源的 URL
postForObject(...) 将数据 POST 到一个 URL,返回从响应主体映射的对象
put(...) 将资源数据 PUT 到指定的URL

除了 TRACE 之外,RestTemplate 对于每个标准 HTTP 方式至少有一个方法。此外,execute()exchange() 为使用任何 HTTP 方式发送请求提供了低层的通用方法。

表 7.2 中的大多数方法都被重载为三种方法形式:

  • 一种是接受一个 String 作为 URL 规范,在一个变量参数列表中指定 URL 参数。
  • 一种是接受一个 String 作为 URL 规范,其中的 URL 参数在 Map<String, String>; 中指定。
  • 一种是接受 java.net.URI 作为 URL 规范,不支持参数化 URL。

一旦了解了 RestTemplate 提供的 12 个操作以及每种变体的工作方式,就可以很好地编写调用资源的 REST 客户端了。

要使用 RestTemplate,需要创建一个实例:

RestTemplate rest = new RestTemplate();

或是将它声明为一个 bean,在需要它的时候将其注入:

@Bean
public RestTemplate restTemplate() {
  return new RestTemplate();
}

让我们通过查看支持四种主要 HTTP 方法(GET、PUT、DELETE 和 POST)的操作来探寻 RestTemplate 的操作。我们将从 getForObject()getForEntity() —— GET 方法开始。

results matching ""

    No results matching ""