百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-06-30 09:50 14 浏览 0 评论

一、简介

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 调用会提高应用程序性能。


相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码