JAVA:Spring WebClient 的应用指南

news2025/1/25 3:29:56

1、简述

随着微服务架构的普及,服务间的 HTTP 通信需求也越来越多。Spring 提供的 WebClient 是 RestTemplate 的替代方案,支持响应式编程,具有非阻塞的特点,非常适合处理高并发的 HTTP 请求。本文将介绍 WebClient 的基本用法及其在实际项目中的使用场景。

在这里插入图片描述


2、核心特点

WebClient 是 Spring 5 引入的一个新的 HTTP 客户端,作为 RestTemplate 的替代方案。RestTemplate 是基于同步阻塞的模型,而 WebClient 是基于响应式编程的模型,提供了更好的性能和扩展性,特别适合在微服务架构中处理非阻塞、高并发的 HTTP 请求。

  • 非阻塞 IO:使用 Reactor 作为响应式框架,具有很好的并发性能。
  • 灵活性:支持 GET、POST、PUT、DELETE 等多种请求方式。
  • 更丰富的功能:支持同步、异步请求,且易于集成 OAuth2 等安全认证机制。

3、基本用法

WebClient 的创建方式有两种:通过 WebClient.create() 创建无参的默认客户端,或者使用 WebClient.builder() 创建带自定义配置的客户端。

3.1 基本 GET 请求
WebClient webClient = WebClient.create("https://api.example.com");

String result = webClient.get()
        .uri("/data")
        .retrieve()
        .bodyToMono(String.class)
        .block(); // 阻塞方法,等待响应
System.out.println("Result: " + result);

在上面的例子中,retrieve() 方法用于获取响应体,bodyToMono(String.class) 表示将响应体解析为 String 类型。调用 block() 方法会阻塞当前线程,直到拿到响应。

3.2 基本 POST 请求
Mono<String> response = webClient.post()
        .uri("/submit")
        .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .bodyValue(new MyRequestObject("sampleData"))
        .retrieve()
        .bodyToMono(String.class);

response.subscribe(result -> System.out.println("Response: " + result));

这里使用了 subscribe() 方法,可以实现异步非阻塞的请求处理。


4、使用场景

以下是一些 WebClient 的常见使用场景,并提供了相应的代码示例。

4.1 微服务间的 RESTful 通信

在微服务架构中,不同服务之间需要通过 HTTP 互相调用。WebClient 提供了异步调用的能力,非常适合在微服务中作为 HTTP 客户端使用。

@Service
public class OrderService {

    private final WebClient webClient;

    public OrderService(WebClient.Builder builder) {
        this.webClient = builder.baseUrl("http://inventory-service").build();
    }

    public Mono<Product> getProductById(String productId) {
        return webClient.get()
                .uri("/products/{id}", productId)
                .retrieve()
                .bodyToMono(Product.class);
    }
}

在这里,OrderService 调用了 inventory-service 微服务的 /products/{id} 接口。通过 Mono 类型返回,整个请求是异步执行的,不会阻塞主线程,从而提升了系统的并发处理能力。

4.2 批量并发请求

有时候我们需要对多个接口或同一个接口进行批量调用。WebClient 的非阻塞特性非常适合处理这种高并发的请求。

public List<Mono<Product>> getProducts(List<String> productIds) {
    return productIds.stream()
            .map(id -> webClient.get()
                    .uri("/products/{id}", id)
                    .retrieve()
                    .bodyToMono(Product.class))
            .collect(Collectors.toList());
}

public List<Product> getAllProducts(List<String> productIds) {
    return Flux.merge(getProducts(productIds))
            .collectList()
            .block();  // 阻塞等待所有请求完成
}

在上例中,getProducts 方法返回每个请求的 Mono,Flux.merge 将所有的请求合并为一个响应流,从而并发地执行这些请求,并最终返回结果列表。

4.3 处理超时和重试机制

在分布式系统中,网络问题可能导致请求超时或失败。WebClient 支持通过 timeout 和 retry 方法来设置超时和重试机制。

public Mono<String> fetchWithTimeoutAndRetry() {
    return webClient.get()
            .uri("/unstable-endpoint")
            .retrieve()
            .bodyToMono(String.class)
            .timeout(Duration.ofSeconds(3)) // 设置超时时间为 3 秒
            .retry(3) // 最多重试 3 次
            .onErrorReturn("Fallback response"); // 如果仍然失败则返回默认值
}

在此示例中,如果请求超过 3 秒未响应,将触发 timeout,并进行最多 3 次重试操作。若所有尝试都失败,则返回 “Fallback response”。

4.4 异步文件上传

WebClient 支持文件上传,适用于处理异步文件传输的场景,比如上传用户头像、导入 CSV 文件等。

public Mono<String> uploadFile(Resource fileResource) {
    return webClient.post()
            .uri("/upload")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData("file", fileResource))
            .retrieve()
            .bodyToMono(String.class);
}

在此示例中,我们使用 BodyInserters.fromMultipartData 将文件资源上传到指定接口。整个上传过程是非阻塞的,非常适合高并发上传的场景。

4.5 OAuth2 认证集成

在调用第三方 API 时,通常需要 OAuth2 认证。WebClient 支持通过 OAuth2 来配置认证,简化了与安全 API 的集成。

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
                new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
        oauth2.setDefaultOAuth2AuthorizedClient(true);
        
        return WebClient.builder()
                .filter(oauth2)
                .baseUrl("https://api.oauth-provider.com")
                .build();
    }
}

在这里,通过 ReactiveOAuth2AuthorizedClientManager 配置了 WebClient 的 OAuth2 认证,确保请求会携带认证 token,从而实现了安全访问。


5、总结

WebClient 是一个强大且灵活的 HTTP 客户端,特别适合在微服务架构中处理复杂的 HTTP 通信需求。相比 RestTemplate,WebClient 提供了更高效的异步和非阻塞能力,支持流式数据处理和多种认证方式。对于高并发、多请求和需要保证响应时效的应用场景,WebClient 提供了更高效的解决方案。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何给自己的域名配置免费的HTTPS How to configure free HTTPS for your domain name

今天有小伙伴给我发私信&#xff0c;你的 https 到期啦 并且随手丢给我一个截图。 还真到期了。 javapub.net.cn 这个网站作为一个用爱发电的编程学习网站&#xff0c;用来存编程知识和面试题等&#xff0c;平时我都用业余时间来维护&#xff0c;并且还自费买了服务器和阿里云…

深度学习 Pytorch 动态计算图与梯度下降入门

在上节末尾我们发现autograd.grad函数可以灵活进行函数某一点的导数和偏导数的运算&#xff0c;但微分运算只是AutoGrad模块中的一小部分功能&#xff0c;本节将继续讲解这个模块的其他常用功能&#xff0c;并在此基础上介绍另一个常用优化算法&#xff1a;梯度下降算法。 imp…

gitlab使用多数据库

1. 说明 默认情况下&#xff0c;GitLab 使用一个单一的应用数据库&#xff0c;称为主数据库。为了扩展 GitLab&#xff0c;您可以将 GitLab 配置为使用多个应用数据库。 设置多个数据库后&#xff0c;GitLab 将使用第二个应用数据库用于 CI/CD 功能&#xff0c;称为 CI 数据库…

Docker网段和服务器ip冲突导致无法访问网络的解决方法

若宿主机所在网络的网段为172.[17-31].xx.xx&#xff0c;则会与Docker本身内部网络间出现冲突&#xff0c;此时需要重新配置Docker默认地址池 一&#xff1a;查看docker的默认网段 route 二&#xff1a;修改docker的默认网段 etc/docker/daemon.json文件增加修改网段信息 {…

HTML<img>标签

例子 如何插入图片&#xff1a; <img src"img_girl.jpg" alt"Girl in a jacket" width"500" height"600"> 下面有更多“自己尝试”的示例。 定义和用法 该<img>标签用于在 HTML 页面中嵌入图像。 从技术上讲&#x…

leetcode_3092. 最高频率的 ID

https://leetcode.cn/problems/most-frequent-ids/description/ 看到这个数据范围 最极端情况 如果nums全为一个数 并且数量取到最大 那么范围是10的10次方 需要longlong储存 这题主要运用了哈希表配合multiset实现 哈希表主要用作存储某个数的出现次数 mst则用于记录出现次…

01学习nodejs的准备工作

01学习nodejs的准备工作 1.回顾与思考1.1为什么JavaScript可以在浏览器中被执行1.2为什么JavaScript可以操作DOM和BOM&#xff1f;1.3浏览器中的JavaScript运行环境1.4JavaScript 能否做后端开发 2.Nodejs简介2.1什么是nodejs2.2 Node.js中的 JavaScript 运行环境2.3 Node.js可…

2024年度总结-CSDN

2024年CSDN年度总结 Author&#xff1a;OnceDay Date&#xff1a;2025年1月21日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 文章目录 2024年CSDN年度总结1. 整体回顾2…

2024年度技术总结——MCU与MEMS和TOF应用实践

引言 2024年对我来说是技术成长与突破的一年。在这一年里&#xff0c;我不仅在技术领域拓展了深度和广度&#xff0c;还通过与客户合作的实际项目&#xff0c;成功实现了从单一MCU到MCU、MEMS与TOF技术融合的跨越。这一过程中&#xff0c;我深刻认识到&#xff0c;技术的进步不…

五、深入了解IoC

IoC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对象。也就是bean的存储。 5.1Bean的存储 共有两类注解类型可以实现&#xff1a; 1.类注解&#xff1a;Controller、Service、Repository、Component、Configuration. 2.方法注…

python-leetcode-有效的字母异位词

242. 有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; class Solution:def isAnagram(self, s: str, t: str) -> bool:return sorted(s) sorted(t)

RHCE实验详解

目录 实验分析 环境拓扑结构 项目需求 主机环境描述 实验步骤 一、密钥互信和主机名更改 二、DNS 三、NGINX 四、MARIADB 五、NFS 六、NTP 七、论坛服务 结果展示及痛点解答 实验分析 环境拓扑结构 项目需求 1. 172.25.250.101 主机上的 Web 服务要求提供 www.ex…

【Unity】ScrollViewContent适配问题(Contentsizefilter不刷新、ContentSizeFilter失效问题)

最近做了一个项目&#xff0c;菜单栏读取数据后自动生成&#xff0c;结果用到了双重布局 父物体 尝试了很多方式&#xff0c;也看过很多大佬的文章&#xff0c;后来自己琢磨了一下&#xff0c;当子物体组件自动生成之后&#xff0c;使用以下以下代码效果会好一些&#xff1a; …

linux如何修改密码,要在CentOS 7系统中修改密码

要在CentOS 7系统中修改密码&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤 1: 登录到系统 在登录提示符 localhost login: 后输入你的用户名。输入密码并按回车键。 步骤 2: 修改密码 登录后&#xff0c;使用 passwd 命令来修改密码&#xff1a; passwd 系统会提…

Qt Creator 15.0.0如何更换主题和字体

1.打开Qt Creator 15.0.0 (Community)&#xff0c; 2.点击编辑栏3.点击Preferences... 4.修改主题&#xff0c;点击环境&#xff0c;修改Theme:栏 5.修改字体大小&#xff0c;点击文本编辑器&#xff0c;修改字号栏。&#xff0c;修改Theme:栏

Java 日志技术、Logback日志框架、日志级别

一. 日志 1. 日志&#xff1a;程序中的日志&#xff0c;通常就是一个文件&#xff0c;里面记录的是程序运行过程中的各种信息。 二. 日志技术 1. 日志技术&#xff1a;可以将系统执行的信息&#xff0c;方便的记录到指定的位置(控制台、文件中、数据库中) 2. 可以随时以开关的…

【多视图学习】显式视图-标签问题:多视图聚类的多方面互补性研究

Explicit View-labels Matter:A Multifacet Complementarity Study of Multi-view Clustering TPAMI 2024 论文链接 代码链接 0.论文摘要 摘要-一致性和互补性是促进多视图聚类&#xff08;MVC&#xff09;的两个关键因素。最近&#xff0c;随着流行的对比学习的引入&#…

Datax可视化工具Datax-web安装部署

文章目录 一、Datax-web官网二、Datax-web介绍 1、Datax-web概述2、架构图3、系统环境要求4、特性支持 三、安装部署 1、环境准备2、Datax-web安装包准备 一、Datax-web官网 github&#xff1a;Datax-web gitee: Datax-web 二、Datax-web介绍 1、Datax-web概述 DataX Web…

Spark Streaming编程基础

文章目录 1. 流式词频统计1.1 Spark Streaming编程步骤1.2 流式词频统计项目1.2.1 创建项目1.2.2 添加项目依赖1.2.3 修改源目录1.2.4 添加scala-sdk库1.2.5 创建日志属性文件 1.3 创建词频统计对象1.4 利用nc发送数据1.5 启动应用&#xff0c;查看结果 2. 编程模型的基本概念3…