弃用 RestTemplate,来了解一下官方推荐的 WebClient 吧!

别再使用 RestTemplate了,试试官方推荐的 WebClient ! 在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用,但鼓励 Spring 开发人员迁移到新项目的 WebClient。设置请求超时不会有任何影响总的来说,虽然 RestTemplate 可能仍然适用于某些用例,但 WebClient 提供了几个优势,使其成为现代 Spring 应用程序的更好选择。 阅读详情

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

ed88473f0d27bae4f423bbe637b2d2b1.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、ERP、CRM、AI 大模型等等功能:

  • Boot 多模块架构:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 微服务架构:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 双版本 

来源:码猿技术专栏


在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用,但鼓励 Spring 开发人员迁移到新项目的 WebClient。

WebClient 优于 RestTemplate 的原因有几个:

  • 非阻塞 I/O :WebClient 构建在 Reactor 之上,它提供了一种非阻塞、反应式的方法来处理 I/O。这可以在高流量应用程序中实现更好的可扩展性和更高的性能。

  • 函数式风格 :WebClient 使用函数式编程风格,可以使代码更易于阅读和理解。它还提供了流畅的 API,可以更轻松地配置和自定义请求。

  • 更好地支持流式传输 :WebClient 支持请求和响应正文的流式传输,这对于处理大文件或实时数据非常有用。

  • 改进的错误处理 :WebClient 提供比 RestTemplate 更好的错误处理和日志记录,从而更轻松地诊断和解决问题。

重点:即使升级了spring web 6.0.0版本,也无法在HttpRequestFactory中设置请求超时,这是放弃使用 RestTemplate 的最大因素之一。

31c0c9f0b434e94ca60dddfc8e680cdb.png

设置请求超时不会有任何影响

总的来说,虽然 RestTemplate 可能仍然适用于某些用例,但 WebClient 提供了几个优势,使其成为现代 Spring 应用程序的更好选择。

让我们看看如何在 SpringBoot 3 应用程序中使用 WebClient。

1 创建网络客户端:

HttpClient httpClient =
        HttpClient.create()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout)
            .responseTimeout(Duration.ofMillis(requestTimeout))
            .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(readTimeout)));

   WebClient client =
        WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build();

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

2 同步发送请求(就像RestTemplate一样)

如果你想坚持使用发送 HTTP 请求并等待响应的老方法,也可以使用 WebClient 实现如下所示的相同功能:

public String postSynchronously(String url, String requestBody) {
  LOG.info("Going to hit API - URL {} Body {}", url, requestBody);
  String response = "";
  try {
    response =
        client
            .method(HttpMethod.POST)
            .uri(url)
            .accept(MediaType.ALL)
            .contentType(MediaType.APPLICATION_JSON)
            .bodyValue(requestBody)
            .retrieve()
            .bodyToMono(String.class)
            .block();

  } catch (Exception ex) {
    LOG.error("Error while calling API ", ex);
    throw new RunTimeException("XYZ service api error: " + ex.getMessage());
  } finally {
    LOG.info("API Response {}", response);
  }

  return response;
}

block()用于同步等待响应,这可能并不适合所有情况,你可能需要考虑subscribe()异步使用和处理响应。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

3 异步发送请求:

有时我们不想等待响应,而是希望异步处理响应,这可以按如下方式完成:

public static Mono<String> makePostRequestAsync(String url, String postData) {
    WebClient webClient = WebClient.builder().build();
    return webClient.post()
            .uri(url)
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .body(BodyInserters.fromFormData("data", postData))
            .retrieve()
            .bodyToMono(String.class);
}

要使用此函数,只需传入要向其发送 POST 请求的 URL 以及要在请求正文中以 URL 编码字符串形式发送的数据。该函数将返回来自服务器的响应,或者如果请求由于任何原因失败,则返回一条错误消息。

请注意,在此示例中,WebClient是使用默认配置构建的。你可能需要根据不同要求进行不同的配置。

另请注意,block()用于同步等待响应,这可能并不适合所有情况。你可能需要考虑subscribe()异步使用和处理响应。

要使用响应,您可以订阅Mono并异步处理响应。下面是一个例子:

makePostRequestAsync( "https://example.com/api" , "param1=value1¶m2=value2" ) 
.subscribe(response -> { 
    // 处理响应
    System.out.println ( response ); 
}, error -> { 
    / / 处理错误
    System.err.println ( error .getMessage ());     
    }
);

subscribe()用于异步处理响应,你可以提供两个 lambda 表达式作为 subscribe() 的参数。如果请求成功并收到响应作为参数,则执行第一个 lambda 表达式;如果请求失败并收到错误作为参数,则执行第二个 lambda 表达式。

4 处理4XX和5XX错误:

public static Mono<String> makePostRequestAsync(String url, String postData) {
    WebClient webClient = WebClient.builder()
            .baseUrl(url)
            .build();
    return webClient.post()
            .uri("/")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .body(BodyInserters.fromFormData("data", postData))
            .retrieve()
            .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new RuntimeException("Client error")))
            .onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new RuntimeException("Server error")))
            .bodyToMono(String.class);
}

在此示例中,该onStatus()方法被调用两次,一次针对 4xx 客户端错误,一次针对 5xx 服务器错误。onStatus() 每次调用都采用两个参数:

  • aPredicate确定错误状态代码是否与条件匹配

  • aFunction用于返回Mono,即要传播到订阅者的错误信息。

如果状态代码与条件匹配,Mono则会发出相应的状态代码,并且Mono链会因错误而终止。在此示例中,Mono 将发出一条 RuntimeException 错误消息,指示该错误是客户端错误还是服务器错误。

5 根据错误状态采取行动:

要根据Mono的subscribe()方法中的错误采取操作,可以在subscribe函数中处理响应的lambda表达式之后添加另一个lambda表达。如果在处理Monumber的过程中出现错误,则执行第二个lambda表达式。

下面是如何使用makePostRequestAsync函数和处理subscribe方法中的错误的更新示例:

makePostRequestAsync("https://example.com/api", "param1=value1&param2=value2")
.subscribe(response -> {
    // handle the response
    System.out.println(response);
}, error -> {
    // handle the error
    System.err.println("An error occurred: " + error.getMessage());
    if (error instanceof WebClientResponseException) {
        WebClientResponseException webClientResponseException = (WebClientResponseException) error;
        int statusCode = webClientResponseException.getStatusCode().value();
        String statusText = webClientResponseException.getStatusText();
        System.err.println("Error status code: " + statusCode);
        System.err.println("Error status text: " + statusText);
    }
});

subscribe方法中的第二个lambda表达式检查错误是否是WebClientResponseException的实例,这是WebClient在服务器有错误响应时抛出的特定类型的异常。如果它是WebClientResponseException的实例,则代码将从异常中提取状态代码和状态文本,并将它们记录到日志中。

还可以根据发生的特定错误在此lambda表达式中添加其他错误处理逻辑。例如,你可以重试请求、回退到默认值或以特定方式记录错误。

6 处理成功响应和错误的完整代码:

responseMono.subscribe(
response -> {
  // handle the response
  LOG.info("SUCCESS API Response {}", response);
},
error -> {
  // handle the error
  LOG.error("An error occurred: {}", error.getMessage());
  LOG.error("error class: {}", error.getClass());

  // Errors / Exceptions from Server
  if (error instanceof WebClientResponseException) {
    WebClientResponseException webClientResponseException =
        (WebClientResponseException) error;
    int statusCode = webClientResponseException.getStatusCode().value();
    String statusText = webClientResponseException.getStatusText();
    LOG.info("Error status code: {}", statusCode);
    LOG.info("Error status text: {}", statusText);
    if (statusCode >= 400 && statusCode < 500) {
      LOG.info(
          "Error Response body {}", webClientResponseException.getResponseBodyAsString());
    }

    Throwable cause = webClientResponseException.getCause();
    LOG.error("webClientResponseException");
    if (null != cause) {
      LOG.info("Cause {}", cause.getClass());
      if (cause instanceof ReadTimeoutException) {
        LOG.error("ReadTimeout Exception");
      }
      if (cause instanceof TimeoutException) {
        LOG.error("Timeout Exception");
      }
    }
  }

  // Client errors i.e. Timeouts etc - 
  if (error instanceof WebClientRequestException) {
    LOG.error("webClientRequestException");
    WebClientRequestException webClientRequestException =
        (WebClientRequestException) error;
    Throwable cause = webClientRequestException.getCause();
    if (null != cause) {
      LOG.info("Cause {}", cause.getClass());
      if (cause instanceof ReadTimeoutException) {
        LOG.error("ReadTimeout Exception");
      }
      
      if (cause instanceof ConnectTimeoutException) {
        LOG.error("Connect Timeout Exception");
      }
    }
  }
});

超时

我们可以在每个请求中设置超时,如下所示:

return webClient
    .method(this.httpMethod)
    .uri(this.uri)
    .headers(httpHeaders -> httpHeaders.addAll(additionalHeaders))
    .bodyValue(this.requestEntity)
    .retrieve()
    .bodyToMono(responseType)
    .timeout(Duration.ofMillis(readTimeout))  // request timeout for this request
    .block();

但是,我们无法在每个请求中设置连接超时,这是WebClient 的属性,只能设置一次。如果需要,我们始终可以使用新的连接超时值创建一个新的 Web 客户端实例。

连接超时、读取超时和请求超时的区别如下:

7c50b7885e566fd27ee31662679434ee.png

结论

由于 RestTemplace 已弃用,开发人员应开始使用 WebClient 进行 REST 调用,非阻塞 I/O 调用肯定会提高应用程序性能。它不仅提供了许多其他令人兴奋的功能,例如改进的错误处理和对流的支持,而且如果需要,它还可以在阻塞模式下使用来模拟 RestTemplate 行为。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,“长按”或“扫描”下方二维码噢:

f26e874257790c89a1894ff9d84f8a2e.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

135b61fe425ed6776d8609e93b682b02.png

59d0803b3a2e5f0bd3b57a2ea89a3df8.pngda315c4f41817da94c2d8f492db41cbc.png7bb1a51d08f95c9803753c97028a597a.png055fb0644160a8d493069350df12341e.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
弃用RestTemplate后,WebClient性能提升450%!Spring官方推荐的异步非阻塞HTTP客户端全解析! 摘要:Spring 5弃用RestTemplate,转向响应式WebClient,带来性能革命。通过4大对比、5个场景(高并发、流式处理、实时监控等)和迁移指南,解析WebClient的非阻塞优势(吞吐量提升5倍+)。尽管存在学习曲线和调试复杂度,WebClient仍是未来趋势,预计2026年成Spring标配,并可能融合AI推理。开发者需掌握响应式编程以应对技术演进。 阅读详情

相关推荐

Spring Boot 4弃用RestTemplate的原因与WebClient迁移指南

HTTP客户端是微服务架构中的核心组件,其性能直接影响系统吞吐量。传统阻塞式客户端如RestTemplate采用同步I/O模型,每个请求独占线程资源,这在并发场景下容易导致线程池耗尽。现代响应式编程通过事件驱动和非阻塞I/O提升资源利用率,Spring WebClient基于Project Reactor实现,支持背压和异步流处理。在电商、金融等高并发领域,响应式客户端能显著提升系统弹性,例如某案例显示WebClient的QPS处理能力是RestTemplate的6倍。Spring Boot 4弃用Rest

weixin_30254435的博客 392

弃用 RestTemplate,来了解一下官方推荐的 WebClient !

在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用,但鼓励 Spring 开发人员迁移到新项目的 WebClient。设置请求超时不会有任何影响总的来说,虽然 RestTemplate 可能仍然适用于某些用例,但 WebClient 提供了几个优势,使其成为现代 Spring 应用程序的更好选择。

深入Java世界:探索编程之美与技术深度 1206

LeGO-LOAM相对LOAM的改进---地面分离的方法-算法原理+代码讲解

实际上此种地⾯分离算法有⼀些简单,我们可以结合激光雷达安装⾼度等其他先验信息进⾏优化,避免将桌子这些当作地面点。LeGO-LOAM中前端改进中很重要的⼀点就是充分利⽤了地⾯点,那⾸先⾃然是提取对地⾯点的提取。理想情况下, 应该接近0,考虑到⼀⽅⾯激光雷达安装也⽆法做到绝对⽔平,另⼀⽅⾯,地⾯也不是绝。对⽔平,因此,这个⾓度会略微⼤于0,考虑到作者实际在草坪之类的场景下运动,因此这个值被设置成。如上图,相邻的两个扫描线束的同⼀列打在地⾯上如AB点所⽰,他们的垂直⾼度差。,计算垂直⾼度差和⽔平⾼度差的⾓度。..

zysss_的博客 776

Spring 官宣正式弃用 RestTemplate ,启用RestClient,保留 WebClient

Spring团队宣布将于7.0版本开始弃用RestTemplate,这款15年历史的HTTP客户端将逐步退出历史舞台。RestTemplate存在扩展性差、异步支持不足等局限,将被现代化的RestClient取代。RestClient提供链式调用、API版本控制等新特性,同时支持平滑迁移现有项目。未来Spring将形成RestClient(同步)和WebClient(响应式)的双轨格局,新项目建议直接使用新方案。

FeelTouch Labs 1486

基于Zynq的便携式γ能谱仪设计与实现

数字多道分析器(DMCA)是核辐射能谱测量的核心设备,其本质是将探测器输出的模拟脉冲按幅度数字化分道,构建能量-计数分布曲线,从而支撑放射性核素识别与定量分析。其技术原理依赖高速采样、数字滤波成形、基线恢复与峰值提取等关键信号处理环节,具备高分辨率、优线性度与强抗干扰能力。在环境监测、核安全巡检与野外地质勘探等场景中,对低功耗、小型化、实时性提出严苛要求。本方案采用Xilinx Zynq-7020异构SoC架构,融合FPGA实时数字信号处理与ARM嵌入式控制,实现软硬协同优化,兼顾算法精度与工程落地性,为国

weixin_33173126的博客 191

华为OD机试双机位C卷-用户入网定期复评(C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【用户入网定期复评】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【用户入网定期复评】。

qq_45776114的博客 841

别再使用 RestTemplate了,来了解一下官方推荐的 WebClient !

在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用,但鼓励 Spring 开发人员迁移到新项目的 WebClient。WebClient 优于 RestTemplate 的原因有几个:「非阻塞 I/O」:WebClient 构建在 Reactor 之上,它提供了一种...

Java知音 1216

全球SAR卫星大盘点与回波数据处理专栏目录

本专栏将详细介绍各国各地区的SAR卫星的特点和性能,以及SAR回波数据的处理方法和技巧。主要介绍民用和商用SAR卫星,帮助你了解商业SAR卫星的最新动态和技术,MATLAB代码将全部开源。以下是专栏目录,持续更新中。

3166

还在使用 RestTemplate?来了解一下官方推荐的 WebClient !

程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 7分钟。来自:网络,侵删在 Spring Framework 5.0 及更高版本中,RestTemplate 已被弃用,取而代之的是较新的 WebClient。这意味着虽然 RestTemplate 仍然可用,但鼓励 Spring 开发人员迁移到新项目的 WebClient。WebClient 优于 RestTemplate ...

良月柒 264

第154章 点云大规模并行处理(GPU加速)

优化点云处理✨ 使用。

yumeiguo的博客 374

电脑硬件:电脑主板上的接口介绍,看完你就懂了

它们主要用于连接老式的键盘和鼠标,虽然速度和兼容性不如USB接口,但在某些特定场合依然发挥着重要作用。PCIe接口是主板上的扩展能力象征,可以连接各种扩展卡,如显卡、声卡、网卡等。电脑主板作为电脑硬件组成关键的部分,今天给大家分享一下电脑主板上有哪些接口,具体每一个接口的特点、使用场景,有需要的朋友可以来了解一下!它们不仅能连接鼠标、键盘、U盘、打印机,还能连接各种外设,如移动硬盘、游戏手柄等。:虽然现在用得越来越少,但在一些特定场合,如工业控制、老旧设备上,仍然需要使用PS/2接口。

IT技术分享社区 2788

Spring 5.0 ‌始弃用RestTemplate,官方推荐WebClient!

Java精选面试题(微信小程序):5000+道面试题和选择题,真实面经,简历模版,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等,在线随时刷题!在 Spring Framework 5.0及更高版本中,RestTemplate 已被弃用,取而代之的是较新的WebClient...

Java精选 176

高分六号WFV预处理详细步骤(辐射校正、大气校正、几何校正)

高分六号WFV传感器获得的影像的预处理分为两个步骤:辐射校正和大气校正,辐射校正为了消除传感器的自身误差,大气校正为了消除大气的折射误差。 一、辐射校正 按照红框中信息进行更改。 辐射校正前地物光谱反射率: 校正后的地物光谱曲线的变化: 二、大气校正 ENVI中大气校正一般采用Flaash模型,但是这个模型需要设置许多的参数十分的麻烦,所以采用ENVI商店(app store,这个也需要下载的)里的Flaash Easy To Use 这个插件,可以快速地进行大气校正。 大气校正后的地物反射率 这

qq_41828818的博客 1万+

还在使用 RestTemplate吗?学习一下官方推荐的 WebClient!

在本文中,我们介绍了官方推荐的WebClient来替代传统的RestTemplate。WebClient具有响应式支持、函数式风格、异步非阻塞和更灵活的配置等优势。使用WebClient可以提高系统性能、并发处理能力和代码可读性。如果你还在使用RestTemplate,现在是时候尝试使用WebClient了!调用RESTful API:可以使用WebClient发送HTTP请求并处理API的响应。例如,可以使用WebClient调用第三方的API来获取用户信息、获取天气数据等。

牛肉胡辣汤 824

2018安徽省青少年信息学奥林匹克(AHOI)初中组

12 种合法的排列分别为:1, 3, 2, 4, 2, 3, 1, 4, 3, 1, 4, 2, 3, 2, 4, 1, 1, 3, 4, 2, 2, 3,4,1,1,4,2,3, 2,4,1,3, 4,1,3,2, 4,2,3,1, 1,4,3,2, 2,4,3,1。分为 2 组,一组的队员实力值是{4, 5, 2, 3},一组是{-4, -3, -5},其中最小的组人数为 3,可以发现没有比 3 更优的分法了。[0, 1, 1, 2]同样不是合法的分组方案,因为出现了两个实力值为 1 的选手。

weixin_42358969的博客 1143

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

突发!Spring 宣布弃用 RestTemplate!!

RestClient 它也采用了一个现代化的 Fluent API 封装,继承了 RestTemplate 的稳定和同步风格,但避开了模板式 API 的局限。RestClient 和 WebClient 是 Spring 新时代的产物,无论你是走常规路线,还是响应式路线,都是官方对应的主流解决方案。好了,今天的分享就到这里了,后续R哥也会继续关注并分享更多的 Java 资讯和干货,关注公众号Java技术栈第一时间推送。,简单易用,常用于在 Java 应用中发起 HTTP 请求,也用于微服务之间的调用。

Java技术栈,分享最主流的Java技术 430

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: 拒绝盲目跟风,分库分表真的不是万能的!
下一篇: vue-office:一站式Office文件预览解决方案
公众号-芋道源码
博客等级 码龄10年 1634粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值