WebClient vs HttpClient:异同对比
在 Java 开发中,进行网络通信是常见的需求。WebClient 和 HttpClient 是两种常用的用于发送 HTTP 请求的工具。它们都具有相似的功能,但在实现细节和用法上存在一些差异。本文将详细介绍 WebClient 和 HttpClient 的异同,帮助您选择适合您项目需求的工具。
1. 引入依赖
首先,我们需要在项目中引入相应的依赖。对于 WebClient,我们可以使用 Spring WebFlux 提供的 spring-webflux 依赖。对于 HttpClient,我们可以使用 Java 11 提供的 java.net.http 包,无需额外引入依赖。
2. 发送 GET 请求
2.1 使用 WebClient
WebClient client = WebClient.create();
Mono<String> result = client.get().uri("https://api.example.com/users").retrieve().bodyToMono(String.class);
String response = result.block();
System.out.println(response);
2.2 使用 HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.example.com/users")).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
3. 发送 POST 请求
3.1 使用 WebClient
WebClient client = WebClient.create();
Mono<String> result = client.post().uri("https://api.example.com/users").bodyValue("{ \"name\": \"John\", \"age\": 30 }").retrieve().bodyToMono(String.class);
String response = result.block();
System.out.println(response);
3.2 使用 HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.example.com/users")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString("{ \"name\": \"John\", \"age\": 30 }")).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
4. 配置超时时间
4.1 使用 WebClient
WebClient client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofSeconds(10)))).build();
4.2 使用 HttpClient
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
5. 异步请求
5.1 使用 WebClient
WebClient client = WebClient.create();
Mono<String> result = client.get().uri("https://api.example.com/users").retrieve().bodyToMono(String.class);
result.subscribe(response -> System.out.println(response));
5.2 使用 HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.example.com/users")).build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body).thenAccept(System.out::println);
6. 错误处理
6.1 使用 WebClient
WebClient client = WebClient.create();
Mono<String> result = client.get().uri("https://api.example.com/users").retrieve().onStatus(HttpStatus::isError, response -> Mono.error(new RuntimeException("Request failed"))).bodyToMono(String.class);
String response = result.block();
System.out.println(response);
6.2 使用 HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.example.com/users")).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {throw new RuntimeException("Request failed");
}
System.out.println(response.body());
7. 性能和扩展性
7.1 WebClient
- 基于 Reactor 和 Netty,支持非阻塞 I/O,适用于高并发场景。
- 集成了 Spring WebFlux 框架,可以与其他 Spring 组件无缝协作。
- 可以通过自定义
ExchangeFilterFunction对请求和响应进行拦截和处理。
7.2 HttpClient
- Java 11 内置的标准库,无需额外引入依赖。
- 提供了更底层的 API,可以更灵活地控制请求和处理响应。
- 支持 HTTP/2,性能较好。
8. 结论使用 WebClient 的优点:
-
非阻塞、异步操作:
WebClient基于响应式编程模型,使用 Reactor 提供的 Mono 和 Flux 类型来表示异步结果。它允许你以非阻塞的方式发送和处理 HTTP 请求,从而提高应用程序的性能和吞吐量。 -
简洁的 API:
WebClient提供了简洁而直观的 API,通过链式调用可以方便地设置请求参数、发送请求和处理响应。它的 API 设计使得代码易于阅读和维护。 -
内置的异常处理:
WebClient提供了丰富的异常处理机制,可以通过onStatus()方法处理不同的 HTTP 状态码和错误情况。这使得处理错误和异常变得更加方便和灵活。 -
集成 Spring 生态系统:
WebClient是 Spring Framework 的一部分,与其他 Spring 组件(如 Spring Boot)无缝集成。它可以与 Spring 的其他功能(如响应式 Web 框架)配合使用,提供全面的开发体验。
9. WebClient 工具类及使用示例
当使用 WebClient 来进行 HTTP 请求时,可以创建一个工具类来封装常用的请求操作。下面是一个示例的 WebClient 工具类,其中包含了 GET、POST、PUT 和 DELETE 方法的实现:
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;public class WebClientUtils {private WebClient webClient;public WebClientUtils(String baseUrl) {this.webClient = WebClient.builder().baseUrl(baseUrl).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).build();}public <T> Mono<T> get(String uri, Class<T> responseType) {return webClient.get().uri(uri).retrieve().bodyToMono(responseType);}public <T> Mono<T> post(String uri, Object request, Class<T> responseType) {return webClient.post().uri(uri).body(BodyInserters.fromValue(request)).retrieve().bodyToMono(responseType);}public <T> Mono<T> put(String uri, Object request, Class<T> responseType) {return webClient.put().uri(uri).body(BodyInserters.fromValue(request)).retrieve().bodyToMono(responseType);}public <T> Mono<T> delete(String uri, Class<T> responseType) {return webClient.delete().uri(uri).retrieve().bodyToMono(responseType);}
}
使用示例:
public class Main {public static void main(String[] args) {WebClientUtils webClientUtils = new WebClientUtils("https://api.example.com");// 发起 GET 请求webClientUtils.get("/users/1", User.class).subscribe(user -> System.out.println("GET response: " + user));// 发起 POST 请求User newUser = new User("John", "Doe");webClientUtils.post("/users", newUser, User.class).subscribe(user -> System.out.println("POST response: " + user));// 发起 PUT 请求User updatedUser = new User("Jane", "Doe");webClientUtils.put("/users/1", updatedUser, User.class).subscribe(user -> System.out.println("PUT response: " + user));// 发起 DELETE 请求webClientUtils.delete("/users/1", Void.class).subscribe(response -> System.out.println("DELETE response: " + response));}
}
请注意,上述代码中的 User 类是一个自定义的 POJO 类,用于表示用户信息。您需要根据实际情况进行相应的定义和调整。
10. 结论
WebClient 和 HttpClient 都是常用的发送 HTTP 请求的工具,具有相似的功能,但在实现细节和用法上存在一些差异。如果您使用 Spring 框架,且对性能要求较高,可以选择 WebClient。如果您使用的是 Java 11 或更高版本,并且对底层控制和灵活性有要求,可以选择 HttpClient。
以上是对 WebClient 和 HttpClient 的异同的详细讲解。希望对大家有所帮助!
👉 💐🌸 公众号请关注 "果酱桑", 一起学习,一起进步! 🌸💐

相关文章:
WebClient vs HttpClient:异同对比
在 Java 开发中,进行网络通信是常见的需求。WebClient 和 HttpClient 是两种常用的用于发送 HTTP 请求的工具。它们都具有相似的功能,但在实现细节和用法上存在一些差异。本文将详细介绍 WebClient 和 HttpClient 的异同,帮助您选择适合您项目…...
ES6中导入import导出export
ES6使用 export 和 import 来导出、导入模块 用法 /** 导出 export *///分别导出 export let name 孙悟空; export function sum(a, b) {return a b; } } //先定义再导出 let age 18 export {age}/** 默认导出 export default */const a 默认导出; export default a;/**…...
【MySQlL学习笔记】(九)内外连接
内外连接 内连接外连接左外连接右外连接 表的连接分为内连和外连 内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。 语法: select 字段 from 表…...
敦煌https证书能做些什么
随着互联网技术的不断发展,人们的生活方式和社交方式也发生了巨大的变化。互联网已经成为人们生活中不可或缺的一部分,它不仅提供了方便快捷的信息获取方式,还为人们提供了一个全新的社交平台。 然而,随着互联网的不断发展&#x…...
React笔记(六)React路由
一、React路由简介 React 官方并没有提供对应的路由插件,因此,我们需要下载第三方的路由插件 —— React Router DOM。 React Router 在 2021 年 11 月份的时候更新 v6 的版本。本次课就主要讲解V6版本 二、路由配置 1、下载路由 在项目根目录中&am…...
【算法系列篇】分治-归并
文章目录 前言什么是归并算法1. 排序数组1.1 题目要求1.2 做题思路1.3 Java代码实现 2. 数组中逆序对2.1 题目要求2.2 做题思路2.3 Java代码实现 3. 计算右侧小于当前元素的个数3.1 题目要求3.2 做题思路3.3 Java代码实现 4. 翻转对4.1 题目要求4.2 做题思路4.3 Java代码实现 总…...
word导出为HTML格式教程,同时也导出图片
在写文档教程时,有时需要借鉴人家的专业文档内容,一般都是word格式文档。word直接复制里面的内容,帐帖到网站编辑器会有很多问题,需要二次清楚下格式才行,而且图片是没办法直接复制到编辑器内的。所以最方便的办法是将…...
事务的优化
例子: 举例:假设我们有一个文件上传的uploadFile方法,在这个方法中我们会先执行上传一个文件到分布式文件系统中的方法addMediaFilesToMinIO( ),上传成功后执行文件资源数据入库的addMediaFilesToDb( ),那么这个时候事务应该加在哪…...
VMware虚拟机安装_新虚拟机创建_CentOS镜像导入_linux指令基本操作
文章目录 1 VMware下载安装1.1 下载网址1.2 安装步骤 2 创建虚拟机与CentOS镜像导入2.1 创建新虚拟机2.2 导入CentOS镜像 3 获取ip与连接Xshell3.1 查看虚拟机ip地址3.2 Xshell使用 1 VMware下载安装 1.1 下载网址 https://www.vmware.com/cn/products/workstation-pro/works…...
Git常用命令用法
参考视频:真的是全能保姆 git、github 保姆级教程入门,工作和协作必备技术,github提交pr - pull request_哔哩哔哩_bilibili 1.Git初始化 首先设置名称和邮箱。然后初始化一下,然后就创建了一个空的Git仓库。 PS D:\golang\oth…...
电子元器件采购的数字化转型:智能采购工具的应用
电子元器件采购的数字化转型是采购领域的一项重要趋势,智能采购工具的应用在此过程中发挥了关键作用。以下是智能采购工具在电子元器件采购数字化转型中的应用方面的一些关键点: 供应链可见性: 智能采购工具可以提供对供应链的实时可见性。通…...
【RuoYi移动端】uni-app中通过vuex的store来实现全局变量的修改和读取
一、在store文件中新建csjVar.js文件 const csjVar {csjMess: [{aaa:"ok"},{bbb:"no"}] } export default csjVar 二、修改store文件中新建index.js文件 import Vue from vue import Vuex from vuex import user from /store/modules/user import gette…...
IPv6改造深化之路
01 IPv6改造问题及整体改造思路 随着“十四五”期间国家政策对IPv6深化改造及规模部署的推动,在IPv6改造过程中出现了越来越多的系统性问题,如图1所示。 图1 关于IPv6改造的各种疑问所有跨设备通信的IT软硬件系统均需要处理IP地址,各领域均需…...
atoi(),isdigit(),isspace(),round()源码
atoi()是一个C标准库函数,用于将字符串转换为对应的整数。 以下是atoi()函数的一种简化版本的示例实现: int atoi(const char* str) {int result 0;int sign 1;int i 0;// 处理空格while (isspace(str[i])) {i;}// 处理正负号if (str[i] - || str[…...
C# 播放音频文件(播放提示音)
使用SoundPlayer播放声音 System.Media名称空间下的类SoundPlayer 可以让我们很方便的播放wav波形声音文件。SoundPlayer类其实就是对winmm.dll文件中API函数的封装。 首先引入命名空间: using System.Media; SoundPlayer player new SoundPlayer(); player.Sou…...
一种编程语言,
前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…...
云原生Kubernetes:K8S常用服务端口
目录 一、理论 1.K8S常用服务端口号 一、理论 1.K8S常用服务端口号 (1)K8S集群 表1 K8S集群端口 协议端口号K8S集群TCP22使用主机驱动通过SSH进行节点配置TCP53集群DNS服务UDP53集群DNS服务TCP2376主机驱动与Docker守护进程通信的TLS端口TCP2379et…...
clickhouse调优配置
一、官方文档地址 clickhouse的配置项主要在 config.xml 或 users.xml 中, 基本上都在 users.xml 里 config.xml https://clickhouse.tech/docs/en/operations/server-configuration-parameters/settings/ users.xml https://clickhouse.tech/docs/en/operatio…...
pdf文件打开后部分文字无法显示
场景:pdf文件在系统内预览正常,但是下载到本地电脑上,使用wps查看,部分标题会消失,只有标题里面的数字还能显示出来 经过一系列排查,发现查看的电脑上缺失了字体,使用wps查看时,缺失…...
MCS-51单片机温度控制系统的设计
一、项目介绍 注塑机是一种常用的制造设备,用于生产塑料制品。在注塑机的工作过程中,溶胶必须达到一定的温度才能被注入模具中进行成型。因此,在注塑机的生产过程中,温度控制是非常重要的一环。 本项目基于MCS-51单片机设计了一…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...
