64、使用 Spring WebFlux 的 WebClient 整合第三方Restful服务

这节的要点:
就是弄两个项目 , 从 端口9090 这个项目,通过 webClient, 去访问 端口8080 的项目,并获取8080项目的数据。

★ RESTful客户端的两种方式

- 应用基于传统的Spring MVC框架,此时考虑使用RestTemplate来整合第三方RESTful服务。RestTemplate就属于传统Spring Web的API。- 应用基于传统的Web Flux框架,此时考虑使用WebClient来整合第三方RESTful服务。WebClient本身就是属于WebFlux API

★ 使用WebClient调用(整合)第三方RESTful服务

如果应用本身使用的WebFlux这种反应式API,使用WebClient来整合第三饭RESTful服务会更好一些。与RestTemplate的区别在于:
它采用的函数式的编程方式,且它返回的数据都是Flux或Mono——它是面向消息发布来编程
Flux(要返回多条数据用这个 Flux 返回类型)
Mono(只返回一条数据用这个 Mono 返回类型)同样使用的反应式、非阻塞的API。使用:
(1)通过预配置的WebClient.Builder对象创建WebClient。不要自己去new一个WebClient(2)调用WebClient对象的如下方法来指定发送请求: delete()|get()|head() |method(HttpMethod method) |patch()|post() |put()
调用如下方法来设置请求头和请求体。
uri() | header() | accept() | body()
调用如下两个方法获取响应:
exchange()| retrieve()

★ WebClient的底层配置

WebClient底层需要依赖自动配置的ClientHttpConnector(HTTP连接器)▲ Spring Boot会根据类加载路径里的类库自动检测使用哪个ClientHttpConnector来驱动WebClient,Spring Boot内置支持Netty的ReactorClientHttpConnector和JettyClientHttpConnector两个实现类。▲ Spring Boot默认会选择ReactorClientHttpConnector作为实现类(它底层依赖于Reactor Netty),Reactor Netty可以同时提供服务器和客户端的实现;- 只要你添加WebFlux的依赖库(spring-boot-starter-webflux),Netty既能提供服务器端的支持,也能提供WebClient所需要的ClientHttpConnector。一句话,你只需要添加spring-boot-starter-webflux,剩下的一切都搞定。- 如果要选择Jetty作为WebFlux应用的服务器(它只能提供服务器端的支持),如果需要WebClient的客户端支持,那就还需要添加Jetty Reactive HTTPClient的客户端JAR包。

★ 对客户端和服务器端同时配置:

  两步:(1)在Spring容器中配置自定义的ReactorResourceFactory(对于Reactor Netty)或JettyResourceFactory(对Jetty生效)。(2)Spring Boot会自动加载、并应用它们对Reactor Netty或Jetty的资源配置进行重写,这样可同时作用于服务器端和客户端。

★ 替换ClientHttpConnector【一般很少这么干,因为这样相当于完全放弃了Spring Boot的自动配置】

只要在Spring容器中配置自己的ClientHttpConnector,Spring Boot就不会再帮我们自动配置ClientHttpConnector。这样就使用了自定义的ClientHttpConnector代替了自动配置的ClientHttpConnector。

★ 定制WebClient(做法完全类似于前面定制RestTemplate)

定制WebClient提供了两种方式:
- 局部式:在调用WebClient.Builder的build()方法构建WebCilent之前,先调用WebClient.Builder的方法对其定制,通过这种方式设置的WebClient.Builder仅对它构建的WebClient起作用。- 全局式:使用WebClientCustomizer进行定制,所有实现WebClientCustomizer接口的Bean会被自动应用到自动配置的WebClient.Builder中,这种定制方式对整个应用范围的WebClient都起作用。—— 此处的定制方式与定制RestTemplate几乎是相同的。

代码演示

RESTful_XML 8080 项目代表 restful 服务的 服务端,生成json响应的,
MyWebClient9090 项目代表 restful 服务的 客户端,发起请求的

这个 RESTful_XML 就是第三方RESTful 服务,MyWebClient 项目通过 WebClient 来整合它

其他代码可以在这篇获取,都是一样的
其他代码是基于这篇—SpringBoot 使用RestTemplate 整合第三方 RESTful 服务 – 延伸的

需求:两个项目 , 从 9090 这个项目,通过 WebClient 去访问 8080 的项目,并获取数据。

WebClient 和 RestTemplate 的区别

WebClient 属于 WebFlux 的 API , 因此需要导入 WebFlux 的依赖库

先导入依赖:
在这里插入图片描述

区别:
WebClient 和 RestTemplate 的依赖注入的区别
在这里插入图片描述

WebClient 和 RestTemplate 的查看所有图书区别
在这里插入图片描述

根据id查看图书
在这里插入图片描述

根据id删除图书
webClient可以把被删除的对象返回回来
在这里插入图片描述

查看测试结果
在这里插入图片描述

根据id修改图书数据

在这里插入图片描述

测试结果
在这里插入图片描述

完整代码

其他代码可以在这篇获取,都是一样的
其他代码是基于这篇—SpringBoot 使用RestTemplate 整合第三方 RESTful 服务 – 延伸的

pom.xml

在这里插入图片描述

ClientController

package cn.ljh.app.controller;import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.Map;@RestController
@RequestMapping("/mybooks")
public class ClientController
{private final WebClient webClient;public ClientController(WebClient.Builder builder){/** 此处的 WebClient.Builder 是来自于Spring 容器的注入,* 因此它所构建的 webClient 已经接收了spring 容器的默认设置* 如果直接创建 WebClient , 那就相当于完全没有利用Spring容器的依赖注入,* 因此完全不能接受spring容器的默认配置,这样后面所介绍的配置 webClient 完全不可能实现配置了*/this.webClient = builder//此处本身就是对 webClient 的定制.baseUrl("http://192.168.43.189:8080/") //webClient 指定基路径//此处还可以对 webClient 进行更多的定制//.............build();}//查看所有图书@GetMapping("/viewBooks")public Flux<Map> viewBooks(){Flux<Map> mapFlux = webClient.get().uri("/books/viewBooks") //访问路径.accept(MediaType.APPLICATION_JSON)  //访问该方法,希望接收响应类型.retrieve() //获取响应数据//将响应数据转换成 Flux(响应集合数据用Flux) 或这 Mono(单个响应数据用 Mono).bodyToFlux(Map.class);return mapFlux;}//根据id查看图书@GetMapping("/{id}")public Mono<Map> getBookById(@PathVariable Integer id){Mono<Map> mapMono = webClient.get().uri("/books/"+id ) //由于地址是静态的,所以可以把id拼接上去.accept(MediaType.APPLICATION_JSON).retrieve()//获取响应,这里的响应不是真正的数据//将响应数据转换成 Flux(响应集合数据用Flux) 或这 Mono(单个响应数据用 Mono).bodyToMono(Map.class); //获取的属于是消息发布者,或者说是一个消息通道return mapMono;}//根据id删除图书@DeleteMapping("/{id}")public Mono<Map> deleteBookById(@PathVariable Integer id){//webClient可以把被删除的对象返回回来Mono<Map> mapMono = webClient.delete().uri("/books/" + id).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(Map.class);return mapMono;}//根据id修改图书@PutMapping("/{id}")public Mono<Map> updateById(@PathVariable Integer id,@RequestBody Map requestData){Mono<Map> mapMono = webClient.put().uri("/books/" + id).accept(MediaType.APPLICATION_JSON)//参数1:看源码,需要是消息发布者,,因为请求参数只有一个数据,不是集合,所以可以把请求参数包装成Mono,安全一些//参数2:指定参数数据的类型.body(Mono.justOrEmpty(requestData), Map.class)//.header() //如果有需要,可以这样指定请求头.retrieve() //获取响应数据.bodyToMono(Map.class);return mapMono;}}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version></parent><groupId>cn.ljh</groupId><artifactId>MyWebClient</artifactId><version>1.0.0</version><name>MyWebClient</name><properties><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--        <dependency>--><!--            <groupId>org.springframework.boot</groupId>--><!--            <artifactId>spring-boot-starter-web</artifactId>--><!--        </dependency>--><!--   WebClient 属于 WebFluxAPI , 因此需要导入 WebFlux 的依赖库    --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107770.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K线学习001-早晨之星1

K线定义 早晨之星&#xff0c;顾名思义&#xff1a;就是在太阳尚未升起的时候&#xff0c;黎明前最黑暗的时刻&#xff0c;一颗明亮的启明星在天边指引着那些走向光明的夜行人&#xff0c;前途当然看好。 早晨之星&#xff0c;即预示着跌势将尽&#xff0c;大盘处于拉升的前夜&…

TSUMU58CDT9-1显示器芯片方案

TSUMU58CDT9-1是用于LCD显示器的整体解决方案图形处理IC&#xff0c;面板分辨率高达WUXGA。它配置了高速集成三adc /PLL、集成DVI/HDMI接收器、高质量显示处理引擎、集成微控制器和支持LVDS面板接口格式的输出显示接口。TSUMU58CDT9-1支持一个灵活的可配置数字输入接口&#xf…

Ansible 自动化运维工具部署主从数据库+读写分离

文章目录 Ansible 自动化运维工具部署主从数据库读写分离一、主从复制和读写分离介绍二、准备工作&#xff08;1&#xff09;节点规划&#xff08;2&#xff09;修改主机名&#xff08;3&#xff09;免密&#xff08;4&#xff09;配置IP映射&#xff08;5&#xff09;安装ansi…

VMware vCenter Server Appliance7小版本升级

本文尝试使用 vCenter Server Appliance 管理界面 (VAMI) 进行对vCenter Server Appliance7应用进行小版本升级&#xff0c;从7.0.3.00100升级到7.0.3.01600。 一、升级前的准备工作 1、检查当前运行环境&#xff08;当前为7.0.3.00100&#xff09; 2、从 VMware官网下载压缩…

WebStorm使用Element组件库

文章目录 WebStorm使用Element组件库1. webstorm使用vue文件2. 首先需要安装Element Plus2. 项目完成引入-以日历为例 WebStorm使用Element组件库 1. webstorm使用vue文件 在Test.vue文件中书写模板,并暴露对外接口 <script> export default {name: "Test" }…

线性表——顺序表(增删查改)

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存 储。在数组上完成数据的增删查改。 静态顺序表——使用定长数组储存数据 静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了&#xff0c;空…

springWeb

springweb就是spring框架中的一个模块&#xff0c;对web层进行了封装&#xff0c;使用起来更加方便。如何方便&#xff1f;参数接收框架进行封装 SpringWeb拥有控制器&#xff0c;接收外部请求&#xff0c;解析参数传给服务层。 SpringWeb运行流程 用户发起请求 ip:端口/项目名…

利用 Python 中的地理空间数据与 GeoPandas

推荐&#xff1a;使用 NSDT编辑器快速搭建3D应用场景 空间数据的真正潜力在于它能够连接数据点及其各自的位置&#xff0c;为高级分析创造无限的可能性。地理空间数据科学是数据科学中的一个新兴领域&#xff0c;旨在利用地理空间信息并通过空间算法和机器学习或深度学习等先进…

车载多通道语音识别挑战赛(ICMC-ASR)丨ICASSP2024

由希尔贝壳、理想汽车、西工大音频语音与语言处理研究组、新加坡南洋理工大学、天津大学、WeNet开源社区、微软、中国信通院等单位发起的“车载多通道语音识别挑战赛”&#xff08;ICMC-ASR&#xff09;将作为IEEE声学、语音与信号处理国际会议&#xff08;ICASSP2024&#xff…

2个U盘安装Windows10的方法推荐!

"我刚刚购买了一块全新的硬盘。我在旧硬盘上安装了 Windows 10 操作系统&#xff0c;现在我希望将它迁移到我的新硬盘上。是否有人可以提供帮助&#xff0c;并指导我该如何进行&#xff1f;我是否只需将旧硬盘插入计算机&#xff0c;然后在 BIOS 中更改启动顺序以启动新硬…

第4篇 vue的基本语法操作以及组件,声明周期,路由的操作

一 vue常用操作案例 1.1 事件渲染 1.数据渲染的方式&#xff1a;使用插值表达式{{}}进行数据渲染 2.数据渲染的方式&#xff1a;以使用 v-bind指令&#xff0c;它的简写的形式就是一个冒号&#xff08;:&#xff09;&#xff0c;v-bind 特性被称为指令。指令带有前缀 v- 代…

element -ui table表格内容无限滚动 使用插件vue-seamless-scroll

使用插件 一、安装组件依赖 npm install vue-seamless-scroll 二、引入组件 import vueSeamlessScroll from "vue-seamless-scroll"; components: { vueSeamlessScroll }, <div class"table-list "><vue-seamless-scroll :class-option"…