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 5的Spring WebFlux库中作为一部分被发布。它提供了流式API,遵循响应式模型。
由于 RestTemplate 的方法暴露了太多的 HTTP 特性,导致了大量重载的方法,使用成本较高。WebClient 是 RestTemplate 的替代品,支持同步和异步调用。它是 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:设置基础 urldefaultHeader:允许设置一个默认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 将自动默认注册 MappingJackson2HttpMessageConverter 或 MappingJacksonHttpMessageConverter,如果在类路径中检测到 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.中值滤波的原理 中值滤波(Median Filter)是一种常用的非线性图像滤波方法,用于去除图像中的椒盐噪声等离群点。它的原理是基于邻域像素值的排序,并将中间值作为当前像素的新值。 2.中值滤波函数 medianBlur() void cv::medianBl…...
Prompt Tuning训练过程
目录 0. 入门 0.1. NLP发展的四个阶段: Prompt工程如此强大,我们还需要模型训练吗? - 知乎 Prompt learning系列之prompt engineering(二) 离散型prompt自动构建 Prompt learning系列之训练策略篇 - 知乎 ptuning v2 的 chatglm垂直领域训练记…...
装备制造企业是否要转型智能装备后服务型公司?
一、从制造到服务:装备制造企业的转型之路 装备制造企业作为国家经济发展的重要支柱,面临着日益激烈的市场竞争。在这样的背景下,越来越多的装备制造企业开始意识到,通过转型为智能装备后服务型公司,可以更好地满足客…...
day-49 代码随想录算法训练营(19) 动态规划 part 10
121.买卖股票的最佳时机 思路一:贪心 不断更新最小买入值不断更新当前值和最小买入值的差值最大值 思路二:动态规划(今天自己写出来了哈哈哈哈哈哈哈) 1.dp存储:dp[i][0] 表示当前持有 dp[i][1]表示当前不持有2.状…...
检查文件名是否含不可打印字符的C++代码源码
本篇文章属于《518抽奖软件开发日志》系列文章的一部分。 我在开发《518抽奖软件》(www.518cj.net)的时候,有时候需要检查输入的是否是合法的文件名,文件名是否含不可打印字符等。代码如下: //----------------------…...
学习笔记-正则表达式
https://www.runoob.com/regexp/regexp-tutorial.html 正则表达式re(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),可以用来描…...
Wireshark TS | 网络路径不一致传输丢包问题
问题背景 网络路径不一致,或者说是网络路径来回不一致,再专业点可以说是网络路径不对称,以上种种说法,做网络方向的工程师肯定会更清楚些,用简单的描述就是: A 与 B 通讯场景,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 自动翻页接口调用时的验证码处理
写在前面 工作中遇到,简单整理理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大…...
IDEA安装翻译插件
IDEA安装翻译插件 File->Settings->Plugins 在Marketplace中,找到Translation,点击Install 更换翻译引擎 勾选自动翻译文档 翻译 鼠标右击->点击Translate...
DBeaver使用
一、导出表结构 二、导出数据CSV 导出数据时DBeaver并没有导出表结构,所以表结构需要额外保存; 导入数据CSV 导入数据时会因外键、字段长度导致失败;...
Nougat:一种用于科学文档OCR的Transformer 模型
随着人工智能领域的不断进步,其子领域,包括自然语言处理,自然语言生成,计算机视觉等,由于其广泛的用例而迅速获得了大量的普及。光学字符识别(OCR)是计算机视觉中一个成熟且被广泛研究的领域。它有许多用途,…...
redis八股1
参考Redis连环60问(八股文背诵版) - 知乎 (zhihu.com) 1.是什么 本质上是一个key-val数据库,把整个数据库加载到内存中操作,定期通过异步操作把数据flush到硬盘持久化。因为纯内存操作,所以性能很出色,每秒可以超过10…...
人工智能基础-趋势-架构
在过去的几周里,我花了一些时间来了解生成式人工智能基础设施的前景。在这篇文章中,我的目标是清晰概述关键组成部分、新兴趋势,并重点介绍推动创新的早期行业参与者。我将解释基础模型、计算、框架、计算、编排和矢量数据库、微调、标签、合…...
Date日期工具类(数据库日期区间问题)
文章目录 前言DateUtils日期工具类总结 前言 在我们日常开发过程中,当涉及到处理日期和时间的操作时,字符串与Date日期类往往要经过相互转换,且在SQL语句的动态查询中,往往月份的格式不正确,SQL语句执行的效果是不同的…...
为什么需要 TIME_WAIT 状态
还是用一下上一篇文章画的图 TCP 的 11 个状态,每一个状态都缺一不可,自然 TIME_WAIT 状态被赋予的意义也是相当重要,咱们直接结论先行 上文我们提到 tcp 中,主动关闭的一边会进入 TIME_WAIT 状态, 另外 Tcp 中的有 …...
Linux——(第七章)文件权限管理
目录 一、基本介绍 二、文件/目录的所有者 1.查看文件的所有者 2.修改文件所有者 三、文件/目录的所在组 1.修改文件/目录所在组 2.修改用户所在组 四、权限的基本介绍 五、rwx权限详解 1.rwx作用到文件 2.rwx作用到目录 六、修改权限 一、基本介绍 在Linux中&…...
Scala在大数据领域的崛起:当前趋势和未来前景
文章首发地址 Scala在大数据领域有着广阔的前景和现状。以下是一些关键点: Scala是一种具有强大静态类型系统的多范式编程语言,它结合了面向对象编程和函数式编程的特性。这使得Scala非常适合处理大数据,因为它能够处理并发、高吞吐量和复杂…...
金融计算、游戏物理引擎必看:C++ double精度到底够不够用?一个实验告诉你答案
金融计算与游戏物理引擎中的C double精度边界:实战测试与技术选型指南 在金融衍生品定价、高频交易系统或大型3D游戏物理引擎开发中,数值精度问题往往成为最隐蔽的"系统杀手"。当某家投行的利率互换产品因累计舍入误差导致千万级损失ÿ…...
四十二、OpenLayers动态航线进阶:从圆弧生成到跨子午线动画优化
1. 大圆弧航线生成的原理与实现 在地理信息系统中,飞机航线通常不是简单的直线连接,而是遵循地球表面的大圆弧路径。这种路径被称为大圆航线,它是球面上两点之间的最短路径。想象一下用一根橡皮筋在地球仪上连接两个城市,橡皮筋自…...
从nnUNetV1到V2:数据增强策略升级对比与调参指南(3D医学影像专用)
从nnUNetV1到V2:数据增强策略升级对比与调参指南(3D医学影像专用) 在医学影像分析领域,nnUNet系列框架因其出色的性能和标准化流程已成为3D图像分割的标杆工具。本文将深入剖析从nnUNetV1到V2的数据增强策略演进,通过对…...
pyLDAvis终极指南:如何用交互式可视化轻松理解主题模型
pyLDAvis终极指南:如何用交互式可视化轻松理解主题模型 【免费下载链接】pyLDAvis Python library for interactive topic model visualization. Port of the R LDAvis package. 项目地址: https://gitcode.com/gh_mirrors/py/pyLDAvis 你是否曾面对一个训练…...
如何用Windows Cleaner轻松拯救你的C盘?3个实用技巧告别爆红烦恼
如何用Windows Cleaner轻松拯救你的C盘?3个实用技巧告别爆红烦恼 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 当你的C盘突然变红,系统卡…...
Attention机制在NLP中的前世今生:从Seq2Seq到Transformer的进化之路
Attention机制在NLP中的进化史:从Seq2Seq到Transformer的技术革命 自然语言处理领域的技术演进如同一部精心编织的史诗,而Attention机制无疑是其中最引人入胜的篇章之一。这项最初为解决机器翻译瓶颈而诞生的技术,如今已成为现代NLP架构的基石…...
OpenClaw+nanobot镜像安全指南:3步设置操作权限边界
OpenClawnanobot镜像安全指南:3步设置操作权限边界 1. 为什么需要权限边界? 上周我在本地部署了nanobot镜像后,差点经历了一场小型灾难。这个基于Qwen3-4B模型的轻量级OpenClaw实现,原本只是想用来处理些简单的文件整理工作。但…...
从破碎到复原:用3Dmax RayFire和虚幻引擎玩转时间倒流特效(含FBX导入设置详解)
从破碎到复原:用3Dmax RayFire和虚幻引擎玩转时间倒流特效(含FBX导入设置详解) 在影视特效和游戏开发领域,"时间倒流"始终是让人着迷的视觉奇观。想象一下:一座坍塌的城堡砖块自动回垒,打碎的玻…...
如何高效管理Open GApps源代码:download_sources.sh脚本完全指南
如何高效管理Open GApps源代码:download_sources.sh脚本完全指南 【免费下载链接】opengapps The main repository of the Open GApps Project 项目地址: https://gitcode.com/gh_mirrors/op/opengapps Open GApps是Android系统中广泛使用的Google应用包项目…...
终极指南:如何快速参与SoloPi开源Android测试工具开发 [特殊字符]
终极指南:如何快速参与SoloPi开源Android测试工具开发 🚀 【免费下载链接】SoloPi 项目地址: https://gitcode.com/gh_mirrors/sol/SoloPi SoloPi是一款无线化、非侵入式的Android自动化测试工具,专为测试开发人员设计,能…...
