环境:Spring Boot3.2.5
1. 简介
从Spring Framework 6.1和Spring Boot 3.2开始,我们可以使用Spring RestClient通过流畅且同步的API执行HTTP请求。RestClient基于底层的HTTP客户端库工作,如JDK HttpClient、Apache HttpComponents等。
顾名思义,RestClient提供了WebClient的流畅API设计和RestTemplate的功能。RestClient在设计时就考虑了可测试性,使得在单元测试中模拟HTTP交互变得更加容易。
请注意,对于异步和流式处理场景,WebClient仍然是首选的API。
RestTemplate、RestClient 和 WebClient 如何选择?
从Spring 6.1开始,与RestTemplate相比,RestClient为同步HTTP访问提供了更现代的API。RestTemplate是Spring 3中引入的,它是一个臃肿的类,以模板类的形式暴露了HTTP的所有功能,但拥有过多的重载方法。
WebClient也支持同步HTTP访问,但它需要额外的依赖spring-boot-starter-webflux。而使用RestClient,我们可以避免在项目中添加新的依赖。
RestTemplate:是一个较旧的、用于发起HTTP请求的同步API。它缺乏新应用程序可能需要的灵活性和现代特性。
WebClient:是Spring WebFlux的反应式、非阻塞客户端部分。尽管它可以用于同步交互,但对于简单的用例来说,它似乎有些过于复杂。
RestClient:是Spring框架的新增成员,旨在取代RestTemplate。它提供了一个像WebClient一样更现代、流畅的API,但不需要反应式堆栈,因此在RestTemplate和WebClient之间找到了一个平衡点。
以下是RestTemplate与WebClient对比:
功能 | WebClient | RestTemplate |
反应式编程 | 基于反应式原理构建,支持反应式编程 | 同步,不是为反应式编程而设计的 |
技术 | 基于反应堆栈 | 基于 Servlet 栈 |
线程模型 | 使用非阻塞 I/O,适合处理大量并发请求 | 使用阻塞 I/O,在高并发情况下可能导致线程阻塞 |
Java版本 | 需要 Java 8 或更高版本。支持函数式编程 | 兼容 Java 6 或更高版本 |
错误处理 | 使用 onErrorResume、onErrorReturn 等操作符提供强大的错误处理功能 | 错误处理通常使用 try-catch 块进行 |
流式 | 使用 Flux 和 Mono 支持流式数据,适用于反应式流式应用场景 | 对流的支持有限,不适合反应式流 |
使用类 | 最适合微服务、反应式应用程序和需要高并发性的应用场景 | 适用于传统的单片式应用和简单用例 |
依赖 | 需要依赖 Spring WebFlux | 需要 Spring Web 依赖关系 |
功能支持 | 与反应式编程模式相一致,并有可能得到持续发展和支持 | 可能会进行维护更新,但今后可能不会受到那么多关注 |
接下来,我将详细的介绍RestClient的使用。
2. 实战案例
2.1 创建RestClient
Spring 允许使用多种灵活的方法来初始化 RestClient Bean。例如,最简单的方法是使用 create() 方法。
我们还可以使用 builder() 方法来设置更复杂的选项,如默认头、请求处理器、消息处理程序等。例如,下面的配置使用 HttpClient 作为 HTTP 连接管理的底层库。
甚至,我们还可以直接通过RestTemplate来构建RestClient对象
2.2 HTTP Get请求
restClient.get() 用于向指定的 URL 创建 GET 请求。请注意,我们可以将动态值传递给 URI 模板。
最后,retrieve() 方法发送请求并返回包含 API 响应的 ResponseSpec。下面的请求将获取用户列表,并将响应体解析为User实例列表。
我们还可以处理,如请求的状态、请求header等数据,可以按如下方式获取响应实体(ResponseEntity):
2.3 HTTP Post请求
restClient.post() 用于处理 POST 请求。除了 POST API 通常不返回任何响应外,其他大部分与 GET API 调用相同。toBodilessEntity() 方法具有完全相同的功能,可用于 POST API。
2.4 HTTP Put请求
restClient.put() 用于处理 PUT 请求。PUT API 通常会发送一个请求正文并接收一个响应正文,如下示例。
2.5 HTTP Delete请求
restClient.delete() 用于处理 DELETE 请求。一般来说,delete API 在服务器中接受,并且不会要求响应体。
2.6 RestClient复杂应用
如果我们需要完全控制响应处理,可以使用 exchange() 方法。它提供了对 HttpRequest 和 HttpResponse 对象的访问权限,然后我们就可以按自己的需要使用它们了。
2.7 异常处理
对于失败的请求,RestClient 会抛出两种异常:
HttpClientErrorException:带 4xx 响应代码
HttpServerErrorException:响应代码为 5xx
2.8 自定义拦截器
我们可以通过RestClient.Builder设置拦截器,通过拦截器我们可以进行日志的记录,认证的配置等等,如下示例:
自定义拦截器
注:RestTemplate与RestClient使用的拦截器是相同的。所以你可以复用之前写的拦截器。
2.9 基于服务发现负载均衡
从Spring Cloud 4.1.0开始RestClient支持服务发现的负载均衡。在RestTemplate时代,我们在定义RestTemplate bean对象时,只要添加了@LoadBalanced注解,那么我们的RestTemplate就可以通过服务名的方式远程调用。
RestClient要通过服务发现机制调用,那么我们就要自定义RestClient.Builder对象。
接下来,我们就可以通过上面自定义的RestClient.Builder来构建RestClient。
这样配置,我们的RestClient就具备服务发现的能力了。