系列文章目录
SpringBoot3-第一篇(快速入门)
SpringBoot3-第二篇(Web开发)
SpringBoot3-第三篇(数据访问)
SpringBoot3-第四篇(基础特性)
SpringBoot3-第五篇(核心原理)
SpringBoot3-第六篇(整合NoSQL)
SpringBoot3-第七篇(整合接口文档)
SpringBoot3-第八篇(整合远程调用)
文章目录
- 系列文章目录
- 1. WebClient
- 1.1 创建与配置
- 1.2 获取响应
- 1.3 定义请求体
- 2. HTTP Interface
- 2.1 导入依赖
- 2.2 定义接口
- 2.3 创建代理&测试
RPC(Remote Procedure Call):远程过程调用
本地过程调用: a(); b(); a() { b();}: 不同方法都在同一个JVM运行
远程过程调用:
- 服务提供者:
- 服务消费者:
- 通过连接对方服务器进行请求\响应交互,来实现调用效果
API/SDK的区别是什么?
- api:接口(Application Programming Interface)
- 远程提供功能;
- sdk:工具包(Software Development Kit)
- 导入jar包,直接调用功能即可
开发过程中,我们经常需要调用别人写的功能
- 如果是内部微服务,可以通过依赖cloud、注册中心、openfeign等进行调用
- 如果是外部暴露的,可以发送 http 请求、或遵循外部协议进行调用
SpringBoot 整合提供了很多方式进行远程调用
- 轻量级客户端方式
- RestTemplate: 普通开发
- WebClient: 响应式编程开发
- Http Interface: 声明式编程
- Spring Cloud分布式解决方案方式
- Spring Cloud OpenFeign
- 第三方框架
- Dubbo
- gRPC
- …
1. WebClient
非阻塞、响应式HTTP客户端
1.1 创建与配置
发请求:
- 请求方式: GET\POST\DELETE\xxxx
- 请求路径: /xxx
- 请求参数:aa=bb&cc=dd&xxx
- 请求头: aa=bb,cc=ddd
- 请求体:
创建 WebClient
非常简单:
WebClient.create()
WebClient.create(String baseUrl)
还可以使用 WebClient.builder()
配置更多参数项:
uriBuilderFactory
: 自定义UriBuilderFactory
,定义 baseurl.defaultUriVariables
: 默认 uri 变量.defaultHeader
: 每个请求默认头.defaultCookie
: 每个请求默认 cookie.defaultRequest
:Consumer
自定义每个请求.filter
: 过滤 client 发送的每个请求exchangeStrategies
: HTTP 消息 reader/writer 自定义.clientConnector
: HTTP client 库设置.
//获取响应完整信息
WebClient client = WebClient.create("https://example.org");
1.2 获取响应
retrieve()
方法用来声明如何提取响应数据。比如
//获取响应完整信息
WebClient client = WebClient.create("https://example.org");Mono<ResponseEntity<Person>> result = client.get().uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON).retrieve().toEntity(Person.class);//只获取body
WebClient client = WebClient.create("https://example.org");Mono<Person> result = client.get().uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(Person.class);//stream数据
Flux<Quote> result = client.get().uri("/quotes").accept(MediaType.TEXT_EVENT_STREAM).retrieve().bodyToFlux(Quote.class);//定义错误处理
Mono<Person> result = client.get().uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON).retrieve().onStatus(HttpStatus::is4xxClientError, response -> ...).onStatus(HttpStatus::is5xxServerError, response -> ...).bodyToMono(Person.class);
1.3 定义请求体
//1、响应式-单个数据
Mono<Person> personMono = ... ;Mono<Void> result = client.post().uri("/persons/{id}", id).contentType(MediaType.APPLICATION_JSON).body(personMono, Person.class).retrieve().bodyToMono(Void.class);//2、响应式-多个数据
Flux<Person> personFlux = ... ;Mono<Void> result = client.post().uri("/persons/{id}", id).contentType(MediaType.APPLICATION_STREAM_JSON).body(personFlux, Person.class).retrieve().bodyToMono(Void.class);//3、普通对象
Person person = ... ;Mono<Void> result = client.post().uri("/persons/{id}", id).contentType(MediaType.APPLICATION_JSON).bodyValue(person).retrieve().bodyToMono(Void.class);
2. HTTP Interface
Spring 允许我们通过定义接口的方式,给任意位置发送 http 请求,实现远程调用,可以用来简化 HTTP 远程访问。需要
webflux
场景才可
2.1 导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2.2 定义接口
public interface BingService {@GetExchange(url = "/search")String search(@RequestParam("q") String keyword);
}
2.3 创建代理&测试
@SpringBootTest
class Boot05TaskApplicationTests {@Testvoid contextLoads() throws InterruptedException {//1、创建客户端WebClient client = WebClient.builder().baseUrl("https://cn.bing.com").codecs(clientCodecConfigurer -> {clientCodecConfigurer.defaultCodecs().maxInMemorySize(256*1024*1024);//响应数据量太大有可能会超出BufferSize,所以这里设置的大一点}).build();//2、创建工厂HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();//3、获取代理对象BingService bingService = factory.createClient(BingService.class);//4、测试调用Mono<String> search = bingService.search("尚硅谷");System.out.println("==========");search.subscribe(str -> System.out.println(str));Thread.sleep(100000);}}