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的一些主要区别:
-
非阻塞:RestTemplate是非阻塞的,而WebClient默认情况下是阻塞的。但是,你可以通过设置client.configurator().setConnectTimeout(Duration.ofSeconds(10))来让WebClient在连接超时时抛出异常。
-
可扩展性:WebClient更容易与其他Spring组件集成,因为它是一个更高级别的抽象。而RestTemplate需要手动创建HttpComponentsClientHttpRequestFactory实例,这可能会比较复杂。
-
支持反应式编程:WebClient完全符合Reactive Streams规范,因此可以很好地与响应式编程框架一起使用。而RestTemplate不支持反应式编程。
-
错误处理:RestTemplate的错误处理是通过回调函数进行的,这使得错误处理变得复杂。而WebClient的错误处理更加直观,因为它支持直接使用try-catch语句捕获异常。
-
配置选项: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请求,并且可以很好地与其他Spring组件集成。WebClient支持同步和异步操作,使得它非常适合用于构建响应式应用程序。 WebClient允…...

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

MySQL 面试知识脑图 初高级知识点
脑图下载地址:https://mm.edrawsoft.cn/mobile-share/index.html?uuid18b10870122586-src&share_type1 sql_mode 基本语法及校验规则 ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现ÿ…...

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

OpenCV4(C++)—— 创建窗口滑动条来调参
文章目录 创建滑动条 —— createTrackbar 创建滑动条 —— createTrackbar createTrackbar是OpenCV中的一个函数,用于创建一个可调节的滑动条(Trackbar),以便在图像处理过程中实时调整参数 int cv::createTrackbar(const String…...

深度学习基础知识 学习率调度器的用法解析
深度学习基础知识 学习率调度器的用法解析 1、自定义学习率调度器**:**torch.optim.lr_scheduler.LambdaLR2、正儿八经的模型搭建流程以及学习率调度器的使用设置 1、自定义学习率调度器**:**torch.optim.lr_scheduler.LambdaLR 实验代码: 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对数据预处理
文章目录 数据处理步骤观察数据数据无量纲化缺失值处理处理分类型特征处理连续型特征 数据处理步骤 数据无量纲化缺失值处理处理分类型特征:编码与哑变量处理连续型特征:二值化与分段 观察数据 通过pandas读取数据,通过head和info方法大致查…...

【智慧燃气】智慧燃气解决方案总体概述--终端层、网络层
关键词:智慧燃气、智慧燃气系统、智慧燃气平台、智慧燃气解决方案、智慧燃气应用、智能燃气 智慧燃气解决方案是基于物联网、大数据、云计算、移动互联网等先进技术,结合燃气行业特征,通过智能设备全面感知企业生产、环境、状态等信息的全方…...

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

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

【考研408常用数据结构】C/C++实现代码汇总
文章目录 前言数组多维数组的原理、作用稀疏数组 链表单向链表的增删改查的具体实现思路约瑟夫环问题(可不学)双向链表 树二叉搜索树中序线索二叉树哈夫曼树的编码与译码红黑树B树B树 堆顺序与链式结构队列实现优先队列排序算法(重点…...

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…...

信息系统项目管理师第四版学习笔记——项目绩效域
干系人绩效域 干系人绩效域涉及与干系人相关的活动和职能。在项目整个生命周期过程中,有效执行本绩效域可以实现的预期目标主要包含:①与干系人建立高效的工作关系;②干系人认同项目目标;③支持项目的干系人提高了满意度…...

PyTorch 深度学习之加载数据集Dataset and DataLoader(七)
1. Revision: Manual data feed 全部Batch:计算速度,性能有问题 1 个 :跨越鞍点 mini-Batch:均衡速度与性能 2. Terminology: Epoch, Batch-Size, Iteration DataLoader: batch_size2, sheffleTrue 3. How to define your Dataset 两种处…...

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

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

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]…...

新手如何快速上手HTTP爬虫IP?
对于刚接触HTTP爬虫IP的新手来说,可能会感到有些困惑。但是,实际上HTTP爬虫IP并不复杂,只要掌握了基本的操作步骤,就可以轻松使用。本文将为新手们提供一个快速上手HTTP爬虫IP的入门指南,帮助您迅速了解HTTP爬虫IP的基…...

(十五)VBA常用基础知识:正则表达式的使用
vba正则表达式的说明 项目说明Pattern在这里写正则表达式,例:[\d]{2,4}IgnoreCase大小写区分,默认false:区分;true:不区分Globaltrue:全体检索;false:最小匹配Test类似p…...

vue配置@路径
第一步:安装path,如果node_module文件夹中有path就不用安装了 安装命令:npm install path --save 第二步:在vue.config.js文件(如果没有就新建)中配置 const path require("path"); function …...

Ubuntu 18.04 OpenCV3.4.5 + OpenCV3.4.5 Contrib 编译
目录 1 依赖安装 2 下载opencv3.4.5及opencv3.4.5 contrib版本 3 编译opencv3.4.5 opencv3.4.5_contrib及遇到的问题 1 依赖安装 首先安装编译工具CMake,命令安装即可: sudo apt install cmake 安装Eigen: sudo apt-get install libeigen3-…...

【网络基础】IP 子网划分(VLSM)
目录 一、 为什么要划分子网 二、如何划分子网 1、划分两个子网 2、划分多个子网 一、 为什么要划分子网 假设有一个B类IP地址172.16.0.0,B类IP的默认子网掩码是 255.255.0.0,那么该网段内IP的变化范围为 172.16.0.0 ~ 172.16.255.255,即…...

【OCR】合同上批量贴印章
一、需求 OCR算法在处理合同等文件时,会由于印章等遮挡导致文本误识别。因此在OCR预处理时,有一个很重要的步骤是“去除印章”。其中本文主要聚焦在“去除印章”任务中的数据构建步骤:“合同伪印章”的数据构建。下面直接放几张批量合成后效果…...

Stable diffusion 用DeOldify给黑白照片、视频上色
老照片常常因为当时的技术限制而只有黑白版本。然而现代的 AI 技术,如 DeOldify,可以让这些照片重现色彩。 本教程将详细介绍如何使用 DeOldify 来给老照片上色。. 之前介绍过基于虚拟环境的 基于DeOldify的给黑白照片、视频上色,本次介绍对于新手比较友好的在Stable diff…...

在服务器上解压.7z文件
1. 更新apt sudo apt-get update2. 安装p7zip sudo apt-get install p7zip-full3. 解压.7z文件 7za x WN18RR.7z...

【opencv】windows10下opencv4.8.0-cuda C++版本源码编译教程
【opencv】windows10下opencv4.8.0-cuda C版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】windows10下opencv4.8.0-cuda C版本源码编译教程前言准备工具cuda/cudnncmakeopencv4.8.0opencv_contrib CMake编译VS2019编…...

软碟通制作启动盘
一、下载并安装软碟通 二、插入U盘,打开软碟通; 三、在软碟通中选择“文件”-“打开镜像文件”,选择要制作成启动盘的ISO镜像文件; 1.打开要制作的iso文件 选择对应的iso文件 四、在软碟通中选择“启动”-“写入硬盘”ÿ…...