当前位置: 首页 > news >正文

Spring6.1之RestClient分析

文章目录

  • 1 RestClient
    • 1.1 介绍
    • 1.2 准备项目
      • 1.2.1 pom.xml
      • 1.2.2 创建全局 RestClient
      • 1.2.3 Get接收数据 retrieve
      • 1.2.4 结果转换 Bean
      • 1.2.5 Post发布数据
      • 1.2.6 Delete删除数据
      • 1.2.7 处理错误
      • 1.2.8 Exchange 方法

1 RestClient

1.1 介绍

Spring 框架一直提供了两种不同的客户端来执行 http 请求:

  • RestTemplate:它在 Spring 3 中被引入,提供同步的阻塞式通信。
    点击了解 Spring之RestTemplate详解
  • WebClient:它在 Spring 5Spring WebFlux 库中作为一部分被发布。它提供了流式 API,遵循响应式模型。

由于 RestTemplate 的方法暴露了太多的 HTTP 特性,导致了大量重载的方法,使用成本较高。WebClientRestTemplate 的替代品,支持同步和异步调用。它是 Spring Web Reactive 项目的一部分。

现在 Spring 6.1 M1 版本引入了 RestClient。一个新的同步 http 客户端,其工作方式与 WebClient 类似,使用与 RestTemplate 相同的基础设施。

1.2 准备项目

1.2.1 pom.xml

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0-M2</version><relativePath/></parent>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

在这里插入图片描述

1.2.2 创建全局 RestClient

创建 RestClient 实例有可用的静态方法:

  • create():委托给默认的 rest 客户端。
  • create(String url):接受一个默认的基础 url。
  • create(RestTemplate restTemplate):基于给定 rest 模板的配置初始化一个新的 RestClient。
  • builder():允许使用 headers、错误处理程序、拦截器等选项自定义一个 RestClient
  • builder(RestTemplate restTemplate):基于给定 RestTemplate 的配置获取一个 RestClient builder

让我们使用 builder 方法调用客户 API 来编写一个 RestClient

RestClient restClient = RestClient.builder().baseUrl(properties.getUrl()).defaultHeader(HttpHeaders.AUTHORIZATION,encodeBasic("pig", "pig")).build();

参数说明:

  • baseUrl:设置基础 url
  • defaultHeader:允许设置一个默认 http 请求头

1.2.3 Get接收数据 retrieve

使用客户端发送 http 请求并接收响应。
RestClient 为每种 HTTP 方法都提供了方法。例如,要搜索所有活动客户,必须执行 GET 请求。retrieve 方法获取响应并声明如何提取它。

让我们从使用完整正文作为 String 的简单情况开始。

String data = restClient.get().uri("?name={name}&type={type}", "lengleng", "1").accept(MediaType.APPLICATION_JSON).retrieve().body(String.class);logger.info(data);

uri 方法可以设置 http 参数第一个参数(一个字符串模板)是附加到 RestClient 中定义的 base url 的查询字符串。第二个参数是模板的 uri 变量(varargs)。

我们还指定媒体类型为 JSON。输出显示在控制台中:

[{"id":1,"name":"lengleng","type":"1"}
]

如果需要检查响应状态码或响应头怎么办,toEntity 方法会返回一个 ResponseEntity

ResponseEntity response = restClient.get().uri("?name={name}&type={type}", "lengleng", "1").accept(MediaType.APPLICATION_JSON).retrieve().toEntity(String.class);logger.info("Status " + response.getStatusCode());
logger.info("Headers " + response.getHeaders());

1.2.4 结果转换 Bean

RestClient 还可以将响应主体转换为 JSON 格式。Spring 将自动默认注册 MappingJackson2HttpMessageConverterMappingJacksonHttpMessageConverter,如果在类路径中检测到 Jackson 2 库或 Jackson 库。但是可以注册自己的消息转换器并覆盖默认设置。

在我们的例子中,响应可以直接转换为记录。例如,检索特定客户的 API:

ReqUserResponse customer = restClient.get().uri("/{name}","lengleng").accept(MediaType.APPLICATION_JSON).retrieve().body(ReqUserResponse.class);logger.info("res name: " + customer.personInfo().name());

要搜索客户,我们只需要使用 List 类,如下所示:

List<ReqUserResponse> customers = restClient.get().uri("?type={type}", "1").accept(MediaType.APPLICATION_JSON).retrieve().body(List.class);logger.info("res size " + customers.size());

1.2.5 Post发布数据

要发送 post 请求,只需调用 post 方法。下一段代码片段创建一个新客户。

ReqUserResponse customer = new ReqUserResponse("lengleng-plus","1"
);ResponseEntity<Void> response = restClient.post().accept(MediaType.APPLICATION_JSON).body(customer).retrieve().toBodilessEntity();if (response.getStatusCode().is2xxSuccessful()) {logger.info("Created " + response.getStatusCode());logger.info("New URL " + response.getHeaders().getLocation());
}

响应代码确认客户已成功创建:

Created 201 CREATED
New URL http://localhost:8080/api/v1/customers/11

要验证客户是否已添加,可以通过 postman 检索以上 URL:

{"id": 2,"name": "lengleng-plus","type": "1"
}

当然,可以使用与前一节类似的代码通过 RestClient 获取它。

1.2.6 Delete删除数据

调用 delete 方法发出 HTTP delete 请求尝试删除资源非常简单。

ResponseEntity<Void> response = restClient.delete().uri("/{id}",2).accept(MediaType.APPLICATION_JSON).retrieve().toBodilessEntity();logger.info("Deleted with status " + response.getStatusCode());

值得一提的是,如果操作成功,响应主体将为空。对于这种情况,toBodilessEntity 方法非常方便。要删除的客户 ID 作为 uri 变量传递。

Deleted with status 204 NO_CONTENT

1.2.7 处理错误

如果我们尝试删除或查询一个不存在的客户会发生什么?客户端点将返回一个 404 错误代码以及消息详细信息。然而,每当接收到客户端错误状态码(400-499)或服务器错误状态码(500-599)时,RestClient 将抛出 RestClientException 的子类。

要定义自定义异常处理程序,有两种选项适用于不同的级别:

RestClient 中使用 defaultStatusHandler 方法(对其发送的所有 http 请求)

RestClient restClient = RestClient.builder().baseUrl(properties.getUrl()).defaultHeader(HttpHeaders.AUTHORIZATION,encodeBasic("pig","pig")).defaultStatusHandler(HttpStatusCode::is4xxClientError,(request, response) -> {logger.error("Client Error Status " + response.getStatusCode());logger.error("Client Error Body "+new String(response.getBody().readAllBytes()));}).build();

在运行删除命令行运行程序后,控制台的输出如下:

Client Error Status 404 NOT_FOUND
Client Error Body {"status":404,"message":"Entity Customer for id 2 was not found.","timestamp":"2023-07-23T09:24:55.4088208"}

另一种选择是为删除操作实现 onstatus 方法。它优先于 RestClient 默认处理程序行为。

ResponseEntity response = restClient.delete().uri("/{id}",2).accept(MediaType.APPLICATION_JSON).retrieve().onStatus(HttpStatusCode::is4xxClientError,(req, res) -> logger.error("Couldn't delete "+res.getStatusText())).toBodilessEntity();if (response.getStatusCode().is2xxSuccessful())logger.info("Deleted with status " + response.getStatusCode());

现在控制台中的消息将是:

Couldn't delete Not Found

1.2.8 Exchange 方法

当响应必须根据响应状态进行不同解码时,exchange 方法很有用。使用 exchange 方法时,状态处理程序将被忽略。

在这个虚构的示例代码中,响应基于状态映射到实体:

SimpleResponse simpleResponse = restClient.get().uri("/{id}",4).accept(MediaType.APPLICATION_JSON).exchange((req,res) ->switch (res.getStatusCode().value()) {case 200 -> SimpleResponse.FOUND;case 404 -> SimpleResponse.NOT_FOUND;default -> SimpleResponse.ERROR;});

相关文章:

Spring6.1之RestClient分析

文章目录 1 RestClient1.1 介绍1.2 准备项目1.2.1 pom.xml1.2.2 创建全局 RestClient1.2.3 Get接收数据 retrieve1.2.4 结果转换 Bean1.2.5 Post发布数据1.2.6 Delete删除数据1.2.7 处理错误1.2.8 Exchange 方法 1 RestClient 1.1 介绍 Spring 框架一直提供了两种不同的客户端…...

冒泡排序、选择排序、插入排序、希尔排序

冒泡排序 基本思想 代码实现 # 冒泡排序 def bubble_sort(arr):length len(arr) - 1for i in range(length):flag Truefor j in range(length - i):if arr[j] > arr[j 1]:temp arr[j]arr[j] arr[j 1]arr[j 1] tempflag Falseprint(f第{i 1}趟的排序结果为&#…...

OpenCV(二十三):中值滤波

1.中值滤波的原理 中值滤波&#xff08;Median Filter&#xff09;是一种常用的非线性图像滤波方法&#xff0c;用于去除图像中的椒盐噪声等离群点。它的原理是基于邻域像素值的排序&#xff0c;并将中间值作为当前像素的新值。 2.中值滤波函数 medianBlur() void cv::medianBl…...

Prompt Tuning训练过程

目录 0. 入门 0.1. NLP发展的四个阶段&#xff1a; Prompt工程如此强大&#xff0c;我们还需要模型训练吗&#xff1f; - 知乎 Prompt learning系列之prompt engineering(二) 离散型prompt自动构建 Prompt learning系列之训练策略篇 - 知乎 ptuning v2 的 chatglm垂直领域训练记…...

装备制造企业是否要转型智能装备后服务型公司?

一、从制造到服务&#xff1a;装备制造企业的转型之路 装备制造企业作为国家经济发展的重要支柱&#xff0c;面临着日益激烈的市场竞争。在这样的背景下&#xff0c;越来越多的装备制造企业开始意识到&#xff0c;通过转型为智能装备后服务型公司&#xff0c;可以更好地满足客…...

day-49 代码随想录算法训练营(19) 动态规划 part 10

121.买卖股票的最佳时机 思路一&#xff1a;贪心 不断更新最小买入值不断更新当前值和最小买入值的差值最大值 思路二&#xff1a;动态规划&#xff08;今天自己写出来了哈哈哈哈哈哈哈&#xff09; 1.dp存储&#xff1a;dp[i][0] 表示当前持有 dp[i][1]表示当前不持有2.状…...

检查文件名是否含不可打印字符的C++代码源码

本篇文章属于《518抽奖软件开发日志》系列文章的一部分。 我在开发《518抽奖软件》&#xff08;www.518cj.net&#xff09;的时候&#xff0c;有时候需要检查输入的是否是合法的文件名&#xff0c;文件名是否含不可打印字符等。代码如下&#xff1a; //----------------------…...

学习笔记-正则表达式

https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式re(Regular Expression)是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;&#xff0c;可以用来描…...

Wireshark TS | 网络路径不一致传输丢包问题

问题背景 网络路径不一致&#xff0c;或者说是网络路径来回不一致&#xff0c;再专业点可以说是网络路径不对称&#xff0c;以上种种说法&#xff0c;做网络方向的工程师肯定会更清楚些&#xff0c;用简单的描述就是&#xff1a; A 与 B 通讯场景&#xff0c;C 和 D 代表中间…...

CMake高级用法实例分析(学习paddle官方的CMakeLists)

cmake基础学习教程 https://juejin.cn/post/6844903557183832078 官方完整CMakeLists cmake_minimum_required(VERSION 3.0) project(PaddleObjectDetector CXX C)option(WITH_MKL "Compile demo with MKL/OpenBlas support,defaultuseMKL." ON) o…...

数据采集: selenium 自动翻页接口调用时的验证码处理

写在前面 工作中遇到&#xff0c;简单整理理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式&#xff0c;是对大…...

IDEA安装翻译插件

IDEA安装翻译插件 File->Settings->Plugins 在Marketplace中&#xff0c;找到Translation&#xff0c;点击Install 更换翻译引擎 勾选自动翻译文档 翻译 鼠标右击->点击Translate...

DBeaver使用

一、导出表结构 二、导出数据CSV 导出数据时DBeaver并没有导出表结构&#xff0c;所以表结构需要额外保存&#xff1b; 导入数据CSV 导入数据时会因外键、字段长度导致失败&#xff1b;...

Nougat:一种用于科学文档OCR的Transformer 模型

随着人工智能领域的不断进步&#xff0c;其子领域&#xff0c;包括自然语言处理&#xff0c;自然语言生成&#xff0c;计算机视觉等&#xff0c;由于其广泛的用例而迅速获得了大量的普及。光学字符识别(OCR)是计算机视觉中一个成熟且被广泛研究的领域。它有许多用途&#xff0c…...

redis八股1

参考Redis连环60问&#xff08;八股文背诵版&#xff09; - 知乎 (zhihu.com) 1.是什么 本质上是一个key-val数据库,把整个数据库加载到内存中操作&#xff0c;定期通过异步操作把数据flush到硬盘持久化。因为纯内存操作&#xff0c;所以性能很出色&#xff0c;每秒可以超过10…...

人工智能基础-趋势-架构

在过去的几周里&#xff0c;我花了一些时间来了解生成式人工智能基础设施的前景。在这篇文章中&#xff0c;我的目标是清晰概述关键组成部分、新兴趋势&#xff0c;并重点介绍推动创新的早期行业参与者。我将解释基础模型、计算、框架、计算、编排和矢量数据库、微调、标签、合…...

Date日期工具类(数据库日期区间问题)

文章目录 前言DateUtils日期工具类总结 前言 在我们日常开发过程中&#xff0c;当涉及到处理日期和时间的操作时&#xff0c;字符串与Date日期类往往要经过相互转换&#xff0c;且在SQL语句的动态查询中&#xff0c;往往月份的格式不正确&#xff0c;SQL语句执行的效果是不同的…...

为什么需要 TIME_WAIT 状态

还是用一下上一篇文章画的图 TCP 的 11 个状态&#xff0c;每一个状态都缺一不可&#xff0c;自然 TIME_WAIT 状态被赋予的意义也是相当重要&#xff0c;咱们直接结论先行 上文我们提到 tcp 中&#xff0c;主动关闭的一边会进入 TIME_WAIT 状态&#xff0c; 另外 Tcp 中的有 …...

Linux——(第七章)文件权限管理

目录 一、基本介绍 二、文件/目录的所有者 1.查看文件的所有者 2.修改文件所有者 三、文件/目录的所在组 1.修改文件/目录所在组 2.修改用户所在组 四、权限的基本介绍 五、rwx权限详解 1.rwx作用到文件 2.rwx作用到目录 六、修改权限 一、基本介绍 在Linux中&…...

Scala在大数据领域的崛起:当前趋势和未来前景

文章首发地址 Scala在大数据领域有着广阔的前景和现状。以下是一些关键点&#xff1a; Scala是一种具有强大静态类型系统的多范式编程语言&#xff0c;它结合了面向对象编程和函数式编程的特性。这使得Scala非常适合处理大数据&#xff0c;因为它能够处理并发、高吞吐量和复杂…...

前端面试经典题--页面布局

题目 假设高度已知&#xff0c;请写出三栏布局&#xff0c;其中左、右栏宽度各为300px&#xff0c;中间自适应。 五种解决方式代码 浮动解决方式 绝对定位解决方式 flexbox解决方式 表格布局 网格布局 源代码 <!DOCTYPE html> <html lang"en"> <…...

【webrtc】接收/发送的rtp包、编解码的VCM包、CopyOnWriteBuffer

收到的rtp包RtpPacketReceived 经过RtpDepacketizer 解析后变为ParsedPayloadRtpPacketReceived 分配内存,执行memcpy拷贝:然后把 RtpPacketReceived 给到OnRtpPacket 传递:uint8_t* media_payload = media_packet.AllocatePayload(rtx_payload.size());RTC...

Bash常见快捷键

生活在 Bash Shell 中&#xff0c;熟记以下快捷键&#xff0c;将极大的提高你的命令行操作效率。 编辑命令 Ctrl a &#xff1a;移到命令行首Ctrl e &#xff1a;移到命令行尾Ctrl f &#xff1a;按字符前移&#xff08;右向&#xff09;Ctrl b &#xff1a;按字符后移&a…...

软件验收测试

1. 服务流程 验收测试 2. 服务内容 测试过程中&#xff0c;根据合同要求制定测试方案&#xff0c;验证工程项目是否满足用户需求&#xff0c;软件质量特性是否达到系统的要求。 3. 周期 10-15个工作日 4. 报告用途 可作为进行地方、省级、国家、部委项目的验收&#xff0…...

Java 与零拷贝

零拷贝是由操作系统实现的&#xff0c;使用 Java 中的零拷贝抽象类库在支持零拷贝的操作系统上运行才会实现零拷贝&#xff0c;如果在不支持零拷贝的操作系统上运行&#xff0c;并不会提供零拷贝的功能。 简述内核态和用户态 Linux 的体系结构分为内核态&#xff08;内核空间…...

AI性能指标解析:误触率与错误率

简介&#xff1a;随着人工智能&#xff08;AI&#xff09;技术的不断发展&#xff0c;它越来越多地渗透到我们日常生活的各个方面。从个人助手到自动驾驶&#xff0c;从语音识别到图像识别&#xff0c;AI正不断地改变我们与世界的互动方式。但你有没有想过&#xff0c;如何准确…...

count(*) 和 count(1) 有什么区别?哪个性能最好?

哪种 count 性能最好&#xff1f; count() 是什么&#xff1f; count() 是一个聚合函数&#xff0c;函数的参数不仅可以是字段名&#xff0c;也可以是其他任意表达式&#xff0c;该函数的作用是统计符合查询条件的记录中&#xff0c;函数指定的参数不为 NULL 的记录由多少条。…...

橡胶密封件为什么会老化?

橡胶密封件以其优良的密封性能被广泛应用于各个行业。然而&#xff0c;随着时间的推移&#xff0c;这些橡胶密封件往往会恶化和老化。在这篇文章中&#xff0c;我们将探讨橡胶密封件老化的原因。 1&#xff0c;导致橡胶密封件老化的主要因素之一是暴露在阳光和紫外线(UV)辐射下…...

Uboot中bootargs以及bootcmd设置

Uboot命令 一、Uboot基础命令 查看帮助信息&#xff1a; uboot#help打印环境变量&#xff1a; uboot#printenv其他命令&#xff1a; uboot#help ? - 帮助命令&#xff0c;等同于 help base - 打印或设置地址偏移量 bdinfo - 打印板级信息结构 boot …...

冠达管理:减肥药概念再度爆发,常山药业两连板,翰宇药业等大涨

减肥药概念12日盘中再度拉升&#xff0c;到发稿&#xff0c;常山药业“20cm”涨停&#xff0c;翰宇药业涨超14%&#xff0c;德展健康涨停&#xff0c;金凯生科涨近9%&#xff0c;争气股份、普利制药、昊帆生物涨约5%&#xff0c;诺泰生物、圣诺生物、华森制药等涨超4%。 常山药…...

岱岳区建设信息网站/外贸网站建站平台

A1 网友年龄 某君新认识一网友。当问及年龄时&#xff0c;他的网友说&#xff1a;“我的年龄是个2位数&#xff0c;我比儿子大27岁&#xff0c;如果把我的年龄的两位数字交换位置&#xff0c;刚好就是我儿子的年龄”    请你计算&#xff1a;网友的年龄一共有多少种可能情况&…...

安庆商务网站建设/百度推广服务费一年多少钱

我在编写客户端 - 服务器应用程序。我有C和Klient中简单内存游戏的游戏服务器。我正在Eclipse中进行开发(一个用于Eclipse的C&#xff0c;一个用于Eclipse的Eclipse)。我使用tpc套接字解决客户端和服务器之间的通信。让我们在服务器上进行基本的操作连接 - 在一种情况下&#x…...

石家庄做网站建设的公司哪家好/百度seo词条优化

因为手机分辨率的原因 有些手机能点击 有些不能 这一度把我的思路引入别的地方了 如下图 我这里不能点击最后找出的原因是被mask组件所在的物体挡住了&#xff0c;即有个黄色框的部分有个mask 看不见 mask貌似会屏蔽同一个canvas里面所有在他区域里面不是他的子物体的UI的用户…...

合肥做个网站什么价格/制作小程序的软件

雷帝网 雷建平 10月15日报道在苏宁小店获3亿美元增资之际&#xff0c;国内便利店行业正面临变局。知情人士日前向雷帝网透露&#xff0c;便利蜂近期获腾讯与高瓴大笔投资&#xff0c;估值16亿美元&#xff0c;腾讯与高瓴分别持股为8%。根据介绍&#xff0c;便利蜂由前去哪儿CEO…...

网站的程序怎么做的/潍坊网站收录

数据库 InnoDB 日志文件大小 这个检查能做什么&#xff1f; 检查您的 MySQL 数据库中的 innodb_log_file_size 变量是否恰当。 结果 Your innodb_log_file_size of 25,165,824 is too small. You should increase innodb_log_file_size to 256M. 【解决】 1.停止Mysql服务 n…...

项目负责人质量建设厅官方网站/上海网站推广服务

在实际的项目中&#xff0c;图片的处理往往是最麻烦的&#xff0c;无论是前后台&#xff0c;我自己也试手了一两个图片上传的小项目&#xff0c;把步骤写下来&#xff0c;以后自己忘记可以返回来看一下&#xff0c;同时希望能够帮到小伙伴们... 前端网页 框架&#xff1a; vue …...