在 Java 服务端开发领域里,Spring 是绕不开的话题,尤其是现在微服务概念盛行,Spring Boot 的出现更是给 Spring 注入了新的活力,除此之外还有 Spring Cloud,这些框架让 Spring 技术体系更加丰富。Spring 从 2014 年的 1.0.0 版本迭代到 现在的 5.2.0 M1 版本,紧随着 Java 语言发展,不断引入新的特性和功能。本文关注的是 Spring 框架中 RestTemplate 内容,可以减少我们平时开发常使用的 HttpClient API 依赖。
首先在我们学习使用 RestTemplate 之前,先认识下这个类,来看 Spring 官方怎么描述的。 从官方 API 文档 RestTemplate javadoc 可以找该类的描述如下:
Synchronous client to perform HTTP requests, exposing a simple, template method API over underlying HTTP client libraries
such as the JDK HttpURLConnection, Apache HttpComponents, and others. The RestTemplate offers templates for common
scenarios by HTTP method, in addition to the generalized exchange and execute methods that support of less frequent cases.
从这里可以清楚地了解到 RestTemplate 采用同步方式执行 HTTP 请求的类,底层使用 JDK 原生 HttpURLConnection API ,或者 HttpComponents等其他 HTTP 客户端请求类库。还有一处强调的就是 RestTemplate 提供模板化的方法让开发者能更简单地发送 HTTP 请求。
值得注意的是,RestTemplate 类是在 Spring Framework 3.0 开始引入的,这里我们使用的 Spring 版本为当前最新的 GA 版本 5.1.6。而在 5.0 以上,官方标注了更推荐使用非阻塞的响应式 HTTP 请求处理类 org.springframework.web.reactive.client.WebClient 来替代 RestTemplate,尤其是对应异步请求处理的场景上 。
这里我们先简单总结下什么是 RestTemplate : RestTemplate 就是 Spring 封装的处理同步 HTTP 请求的类。具体如何使用这个类进行 HTTP 请求操作,可见文章的实战部分。
接下来我们看下 RestTemplate 类提供的 API 有哪些,RestTemplate 提供了将近 30 个请求方法,其中多数是单个方法重载实现,这里我主要参考官方文档 rest-client-access 进行如下分类:
看到那么多方法也记不全,为了更好理解,可以简单看下 RestTemplate 的类层级体系,通过官方源代码就能看到:
/**
* Interface specifying a basic set of RESTful operations.
* Implemented by {@link RestTemplate}. Not often used directly, but a useful
* option to enhance testability, as it can easily be mocked or stubbed.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 3.0
* @see RestTemplate
*/
public interface RestOperations {
...
}
其实 RestTemplate 类的请求方法都是来自 RestOperations 接口的,根据这个名字就可以大概知道这个接口主要就是提供了 RESTful 请求操作的接口,如 GET,POST,PUT,DELETE 等,具体信息可以参见 RestOperation javadoc。
来自Wikipedia 定义:表现层状态转换,一种设计提供万维网络服务的软件构建风格,又简称为 REST。
用 URL 定位资源,用 HTTP 动词描述操作,如 GET,POST,DELETE,PUT,简单来说通过 URL 就知道访问什么资源,通过 HTTP Method 就知道执行什么操作,通过 HTTP Status Code 就知道执行结果。
好了,简单认识了 RestTemplate 类之后,我们先牛刀小试,看看如何上手使用。
@RequestMapping("/product")
@RestController
public class ProductController {
@GetMapping("/get_product1")
public Product get_product1() {
return new Product(1, "ProductA", BigDecimal.valueOf(6666.0));
}
@GetMapping("/get_product2")
public Product get_product2(Integer id) {
return new Product(id, "ProductC", BigDecimal.valueOf(6666.0));
}
@GetMapping("/get_product3")
public String get_product3(