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单片机设计了一…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

SQL注入篇-sqlmap的配置和使用
在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap,但是由于很多朋友看不了解命令行格式,所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习,链接:https://wwhc.lanzoue.com/ifJY32ybh6vc…...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...

【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2
----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导,采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…...

【JMeter】后置处理器 - 提取器
文章目录 概览边界提取器正则提取器JSON提取器 概览 CSS/JQuery提取器;给网页使用JSON提取器:给JSON数据使用★边界提取器:给字符串使用★正则表达式提取器:更加高级的字符使用★Xpath提取器:给网页使用 边界提取器…...

行为设计模式之Iterator(迭代器)
行为设计模式之Iterator(迭代器) 摘要: 迭代器模式(Iterator)是一种行为设计模式,它提供顺序访问聚合对象元素的方法,同时不暴露内部结构。该模式由迭代器接口(Iterator)、具体迭代器(ConcreteIterator)、聚合接口(Ag…...