当前位置: 首页 > news >正文

Spring WebClient 基于响应式编程模型的HTTP客户端

图片

一、简介

WebClient是一个非阻塞的、可扩展的、基于Reactive Streams规范的HTTP客户端。它提供了一种简洁的方式来进行HTTP请求,并且可以很好地与其他Spring组件集成。WebClient支持同步和异步操作,使得它非常适合用于构建响应式应用程序。

WebClient允许开发者通过构建链式的HTTP请求和响应处理函数来构建异步和非阻塞式的HTTP客户端。它支持多种HTTP方法、请求和响应处理、错误处理、HTTP认证和与RESTful服务交互。

二、特性

非阻塞:WebClient使用非阻塞I/O模型,这意味着它可以在等待服务器响应时执行其他任务,从而提高应用程序的性能。

可扩展性:WebClient可以轻松地与其他Spring组件集成,如Spring MVC、Spring Data REST等。此外,它还支持自定义拦截器和转换器,以满足特定的需求。

支持反应式编程:WebClient完全符合Reactive Streams规范,因此可以很好地与响应式编程框架(如RxJava、Reactor等)一起使用。

简化HTTP请求:WebClient提供了简洁的API,使得发送HTTP请求变得更加容易。例如,你可以使用webClient.get()方法来发送一个GET请求,或者使用webClient.postForEntity()方法来发送一个POST请求并接收一个实体对象。

三、WebClient与RestTemplate区别

RestTemplate是Spring提供的一个基于模板化的HTTP客户端,它已经过时,不再建议使用。以下是WebClient与RestTemplate的一些主要区别:

  1. 非阻塞:RestTemplate是非阻塞的,而WebClient默认情况下是阻塞的。但是,你可以通过设置client.configurator().setConnectTimeout(Duration.ofSeconds(10))来让WebClient在连接超时时抛出异常。

  2. 可扩展性:WebClient更容易与其他Spring组件集成,因为它是一个更高级别的抽象。而RestTemplate需要手动创建HttpComponentsClientHttpRequestFactory实例,这可能会比较复杂。

  3. 支持反应式编程:WebClient完全符合Reactive Streams规范,因此可以很好地与响应式编程框架一起使用。而RestTemplate不支持反应式编程。

  4. 错误处理:RestTemplate的错误处理是通过回调函数进行的,这使得错误处理变得复杂。而WebClient的错误处理更加直观,因为它支持直接使用try-catch语句捕获异常。

  5. 配置选项:RestTemplate的配置选项较少,而WebClient提供了更多的配置选项,如连接超时、重试策略等。

四、Spring Boot集成WebClient

在Spring Boot中集成WebClient非常简单,只需添加以下依赖即可:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

接下来,我们创建一个WebClient实例,并演示如何发送同步和异步请求:


import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;public class WebClientExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.create("https://api.example.com");// 发送一个GET请求并接收一个Mono<String>对象(同步请求)Mono<String> response = webClient.get().uri("/resource").retrieve().bodyToMono(String.class);response.subscribe(System.out::println, Throwable::printStackTrace); // 打印响应结果或错误信息// 发送一个POST请求并接收一个Mono<String>对象(异步请求)Mono<String> asyncResponse = webClient.post().uri("/resource").bodyValue("Hello, World!") // 设置请求体内容.retrieve() // 返回响应体而不是完整的响应对象.bodyToMono(String.class); // 将响应体转换为Mono<String>对象asyncResponse.subscribeOn(Schedulers.boundedElastic()) // 指定异步执行的任务线程池.subscribe(System.out::println, Throwable::printStackTrace); // 打印响应结果或错误信息}
}

在这个示例中,我们首先创建了一个WebClient实例,然后使用get()方法发送一个GET请求并接收一个Mono<String>对象。我们使用uri()方法指定请求的URI,然后调用retrieve()方法来获取响应体。最后,我们使用bodyToMono()方法将响应体转换为一个Mono<String>对象,并订阅它以打印结果。

五、网络客户端

Spring WebClient是一个基于Reactive Streams规范的非阻塞式HTTP客户端,它提供了创建网络客户端的功能。下面是使用Spring WebClient创建网络客户端的示例代码:

import org.springframework.web.reactive.function.client.WebClient;public class WebClientExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.create("https://api.example.com");// 发送一个GET请求并接收一个Mono<String>对象Mono<String> response = webClient.get().uri("/resource").retrieve().bodyToMono(String.class);// 订阅响应并打印结果response.subscribe(System.out::println);}
}

在这个示例中,我们首先创建了一个WebClient实例,然后使用get()方法发送一个GET请求并接收一个Mono<String>对象。我们使用uri()方法指定请求的URI,然后调用retrieve()方法来获取响应体。最后,我们使用bodyToMono()方法将响应体转换为一个Mono<String>对象,并订阅它以打印结果。

除了发送GET请求外,我们还可以使用其他方法来发送不同类型的请求,例如POST、PUT和DELETE等。例如,我们可以使用post()方法发送一个POST请求:


import org.springframework.web.reactive.function.client.WebClient;public class WebClientExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.create("https://api.example.com");// 发送一个POST请求并接收一个Mono<String>对象Mono<String> response = webClient.post().uri("/resource").bodyValue("Hello, World!") // 设置请求体内容.retrieve() // 返回响应体而不是完整的响应对象.bodyToMono(String.class); // 将响应体转换为Mono<String>对象// 订阅响应并打印结果response.subscribe(System.out::println);}
}

在这个示例中,我们使用post()方法发送一个POST请求,并使用bodyValue()方法设置请求体内容。我们同样使用retrieve()方法来获取响应体,并使用bodyToMono()方法将响应体转换为一个Mono<String>对象。最后,我们订阅这个Mono对象以打印响应结果。

六、错误处理机制

Spring WebClient提供了多种错误处理机制,包括异常处理、重试策略和自定义错误处理。下面将分别介绍这些错误处理方式,并给出相应的代码示例。

6.1 异常处理

WebClient支持使用onErrorResume方法来处理请求过程中发生的异常。例如:


import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;public class WebClientExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.create("https://api.example.com");// 发送一个GET请求并处理异常Mono<String> response = webClient.get().uri("/resource").retrieve().onErrorResume(e -> {// 打印异常信息System.err.println("Request failed: " + e.getMessage());// 返回一个空的Mono对象,表示请求失败return Mono.empty();});response.subscribe(System.out::println, Throwable::printStackTrace); // 打印响应结果或错误信息}
}

在这个示例中,我们使用onErrorResume方法来处理请求过程中发生的异常。当发生异常时,我们打印异常信息,并返回一个空的Mono对象,表示请求失败。

6.2 重试策略

WebClient支持多种重试策略,如固定延迟重试、指数退避重试等。以下是使用固定延迟重试的示例:


import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;public class WebClientRetryExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.builder().baseUrl("https://api.example.com").clientConnector(new ReactorClientHttpConnector()).build();// 发送一个GET请求并设置重试策略Mono<String> response = webClient.get().uri("/resource").retrieve().bodyToMono(String.class).retryWhen(e -> e instanceof java.net.SocketTimeoutException || e instanceof java.net.UnknownHostException) // 当发生SocketTimeoutException或UnknownHostException时进行重试.delayElements(Duration.ofSeconds(1)); // 设置重试间隔为1秒response.subscribe(System.out::println, Throwable::printStackTrace); // 打印响应结果或错误信息}
}

在这个示例中,我们使用retryWhen方法来设置重试策略。当发生SocketTimeoutException或UnknownHostException时,我们进行重试。同时,我们使用delayElements方法来设置重试间隔。

6.3 自定义错误处理

除了使用异常处理和重试策略外,你还可以通过实现ClientResponse接口来自定义错误处理逻辑。例如:


import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;public class CustomErrorHandlingExample {public static void main(String[] args) {// 创建一个WebClient实例WebClient webClient = WebClient.create("https://api.example.com");// 发送一个GET请求并自定义错误处理逻辑Mono<String> response = webClient.get().uri("/resource").retrieve().onStatus(status -> status.is4xxClientError(), clientResponse -> {// 当发生4xx客户端错误时,返回一个空的Mono对象,表示请求失败return Mono.empty();}).onStatus(status -> status.is5xxServerError(), clientResponse -> {// 当发生5xx服务器错误时,返回一个空的Mono对象,表示请求失败return Mono.empty();});response.subscribe(System.out::println, Throwable::printStackTrace); // 打印响应结果或错误信息}
}

在这个示例中,我们使用onStatus方法来自定义错误处理逻辑。当发生4xx客户端错误或5xx服务器错误时,我们返回一个空的Mono对象,表示请求失败。

七、结语

在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。由于 RestTemplace 已弃用,开发人员应开始使用 WebClient 进行 REST 调用,非阻塞 I/O 调用会提高应用程序性能。

图片

相关文章:

Spring WebClient 基于响应式编程模型的HTTP客户端

一、简介 WebClient是一个非阻塞的、可扩展的、基于Reactive Streams规范的HTTP客户端。它提供了一种简洁的方式来进行HTTP请求&#xff0c;并且可以很好地与其他Spring组件集成。WebClient支持同步和异步操作&#xff0c;使得它非常适合用于构建响应式应用程序。 WebClient允…...

IP真人识别方法与代理IP检测技术

随着互联网的发展&#xff0c;IP地址在网络安全和数据分析中扮演着重要的角色。为了维护网络的安全性和识别真实用户&#xff0c;IP地址的真实性和来源成为了一个关键问题。 什么是IP真人识别&#xff1f; IP真人识别是一种技术&#xff0c;旨在确定IP地址背后的用户是否为真实…...

MySQL 面试知识脑图 初高级知识点

脑图下载地址&#xff1a;https://mm.edrawsoft.cn/mobile-share/index.html?uuid18b10870122586-src&share_type1 sql_mode 基本语法及校验规则 ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作&#xff0c;如果在SELECT中的列&#xff0c;没有在GROUP BY中出现&#xff…...

【数据结构】二叉树的链式结构及实现

目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 1. 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构…...

OpenCV4(C++)—— 创建窗口滑动条来调参

文章目录 创建滑动条 —— createTrackbar 创建滑动条 —— createTrackbar createTrackbar是OpenCV中的一个函数&#xff0c;用于创建一个可调节的滑动条&#xff08;Trackbar&#xff09;&#xff0c;以便在图像处理过程中实时调整参数 int cv::createTrackbar(const String…...

深度学习基础知识 学习率调度器的用法解析

深度学习基础知识 学习率调度器的用法解析 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR2、正儿八经的模型搭建流程以及学习率调度器的使用设置 1、自定义学习率调度器**&#xff1a;**torch.optim.lr_scheduler.LambdaLR 实验代码&#xff1a; i…...

【JUC系列-12】深入理解PriorityQueue的底层原理和基本使用

JUC系列整体栏目 内容链接地址【一】深入理解JMM内存模型的底层实现原理https://zhenghuisheng.blog.csdn.net/article/details/132400429【二】深入理解CAS底层原理和基本使用https://blog.csdn.net/zhenghuishengq/article/details/132478786【三】熟练掌握Atomic原子系列基本…...

Paddle安装

Paddle安装参考 docs/tutorials/INSTALL_cn.md PaddlePaddle/PaddleDetection - Gitee.comhttps://gitee.com/paddlepaddle/PaddleDetection/blob/release/2.6/docs/tutorials/INSTALL_cn.md # 不指定版本安装paddle-gpu python -m pip install paddlepaddle-gpu# 测试安装 …...

配置XP虚拟机和Win 10宿主机互相ping通

文章目录 一、关闭虚机和宿主机的防火墙1、关闭虚拟机的防火墙1.1方式一1.2方式二 2、关闭宿主机的防火墙 二、设置XP和宿主机VMnet8的IP地址、网关和DNS1、获取VMWare的虚拟网络配置信息2、设置XP的VMnet8的IP地址、网关和DNS3、设置宿主机VMnet8的IP地址、网关和DNS 三、获取…...

【机器学习】sklearn对数据预处理

文章目录 数据处理步骤观察数据数据无量纲化缺失值处理处理分类型特征处理连续型特征 数据处理步骤 数据无量纲化缺失值处理处理分类型特征&#xff1a;编码与哑变量处理连续型特征&#xff1a;二值化与分段 观察数据 通过pandas读取数据&#xff0c;通过head和info方法大致查…...

【智慧燃气】智慧燃气解决方案总体概述--终端层、网络层

关键词&#xff1a;智慧燃气、智慧燃气系统、智慧燃气平台、智慧燃气解决方案、智慧燃气应用、智能燃气 智慧燃气解决方案是基于物联网、大数据、云计算、移动互联网等先进技术&#xff0c;结合燃气行业特征&#xff0c;通过智能设备全面感知企业生产、环境、状态等信息的全方…...

Tomcat隔离web原理和热加载热部署

Tomcat 如何打破双亲委派机制 Tomcat 的自定义类加载器 WebAppClassLoader 打破了双亲委派机制&#xff0c;它首先自己尝试去加载某个类&#xff0c;如果找不到再代理给父类加载器&#xff0c;其目的是优先加载 Web 应用自己定义的类。具体实现就是重写 ClassLoader 的两个方法…...

使用ffmpeg和python脚本下载网络视频m3u8(全网最全面)

网上给娃找了些好看的电影和一些有趣的短视频&#xff0c;如何保存下来呢&#xff1f;从网上找各种工具&#xff1f;都不方便。于是想到何不编程搞定&#xff0c;搞个脚本。对程序员来说这都不是事儿。且我有华为云服务器&#xff0c;完全可以把地址记下&#xff0c;后台自动下…...

【考研408常用数据结构】C/C++实现代码汇总

文章目录 前言数组多维数组的原理、作用稀疏数组 链表单向链表的增删改查的具体实现思路约瑟夫环问题&#xff08;可不学&#xff09;双向链表 树二叉搜索树中序线索二叉树哈夫曼树的编码与译码红黑树B树B树 堆顺序与链式结构队列实现优先队列排序算法&#xff08;重点&#xf…...

Flink学习笔记(二):Flink内存模型

文章目录 1、配置总内存2、JobManager 内存模型3、TaskManager 内存模型4、WebUI 展示内存5、Flink On YARN 模式下内存分配6、Flink On Yarn 集群消耗资源估算6.1、资源分配6.2、Flink 提交 Yarn 集群的相关命令6.3、Flink On Yarn 集群的资源计算公式 1、配置总内存 Flink J…...

信息系统项目管理师第四版学习笔记——项目绩效域

干系人绩效域 干系人绩效域涉及与干系人相关的活动和职能。在项目整个生命周期过程中&#xff0c;有效执行本绩效域可以实现的预期目标主要包含&#xff1a;①与干系人建立高效的工作关系&#xff1b;②干系人认同项目目标&#xff1b;③支持项目的干系人提高了满意度&#xf…...

PyTorch 深度学习之加载数据集Dataset and DataLoader(七)

1. Revision: Manual data feed 全部Batch&#xff1a;计算速度&#xff0c;性能有问题 1 个 &#xff1a;跨越鞍点 mini-Batch:均衡速度与性能 2. Terminology: Epoch, Batch-Size, Iteration DataLoader: batch_size2, sheffleTrue 3. How to define your Dataset 两种处…...

小谈设计模式(26)—中介者模式

小谈设计模式&#xff08;26&#xff09;—中介者模式 专栏介绍专栏地址专栏介绍 中介者模式分析角色分析抽象中介者&#xff08;Mediator&#xff09;具体中介者&#xff08;ConcreteMediator&#xff09;抽象同事类&#xff08;Colleague&#xff09;具体同事类&#xff08;C…...

7种设计模式

1. 工厂模式 优点&#xff1a;封装了对象的创建过程&#xff0c;降低了耦合性&#xff0c;提供了灵活性和可扩展性。 缺点&#xff1a;增加了代码的复杂性&#xff0c;需要创建工厂类。 适用场景&#xff1a;当需要根据不同条件创建不同对象时&#xff0c;或者需要隐藏对象创建…...

el-table合计行合并

效果如下 因为合计el-table的合并方法是不生效的,所以需要修改css下手 watch: {// 应急物资的合计合并planData: {immediate: true,handler() {setTimeout(() > {const tds document.querySelectorAll(".pro_table .el-table__footer-wrapper tr>td");tds[0]…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...