Spring6.1之RestClient分析

news2024/11/25 4:41:30

文章目录

  • 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;
    }
  );

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

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

相关文章

DataX(MySQL同步数据到Doris)

1.场景 这里演示介绍的使用 Doris 的 Datax 扩展 DorisWriter实现从Mysql数据定时抽取数据导入到Doris数仓表里 2.编译 DorisWriter 这个的扩展的编译可以不在 doris 的 docker 编译环境下进行&#xff0c;本文是在 windows 下的 WLS 下进行编译的 首先从github上拉取源码 …

升哲科技城市级“算力+数字底座”服务亮相2023服贸会

9月2日至6日&#xff0c;以“开放引领发展&#xff0c;合作共赢未来”为主题的2023年中国国际服务贸易交易会在北京隆重举办。作为城市级数据服务商&#xff0c;升哲科技&#xff08;SENSORO&#xff09;连续第四年参加服贸会&#xff0c;携城市级“算力数字底座”服务及在城市…

语音芯片WTN6的驱动

前言 &#xff08;1&#xff09;本系列是基于STM32的项目笔记&#xff0c;内容涵盖了STM32各种外设的使用&#xff0c;由浅入深。 &#xff08;2&#xff09;小编使用的单片机是STM32F105RCT6&#xff0c;项目笔记基于小编的实际项目&#xff0c;但是博客中的内容适用于各种单片…

java八股文面试[数据库]——MySQL中事务的特性

在关系型数据库管理系统中&#xff0c;一个逻辑工作单元要成为事务&#xff0c;必须满足这 4 个特性&#xff0c;即所谓的 ACID&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;和持…

[移动通讯]【Carrier Aggregation-3】【5G】

前言&#xff1a; 参考&#xff1a; 5G Mobile Communications&#xff1a;《Carrier Aggregation in 5G》 目录&#xff1a; 1&#xff1a; carrier Allocation Schemes 2&#xff1a; 网络结构 3&#xff1a; LTE CA 4: 5G CA 一 Carrier Allocation Schemes CA 主要作用…

问脉基础调研

基本功能&#xff1a; 资产清点 清点镜像、镜像软件资产数据与详细信息清点容器、应用软件资产数据与详细信息清点集群、Pod、Service、Ingress、Secrets 等数十种资产数据与详细信息提供资产与资产、资产与事件关联查看提供仪表盘总览当前检测对象数据情况 镜像安全 镜像漏…

Text文件在MATLAB中读写示例基础

背景 为了便于和外部程序进行交换&#xff0c;以及查看文件中的数据&#xff0c;也常常采用文本数据格式与外界交换数据。在文本格式中&#xff0c;数据采用ASCII码格式&#xff0c;可以使用字母和数字字符。可以在文本编辑器中查看和编辑ASCII文本数据。MATLAB提供了导入函数…

raise EOFError(“No data left in file“) EOFError: No data left in file

在linux服务器里跑分割模型的时候出现了以下错误&#xff0c;但是在自己电脑上运行相同程序时没有错误&#xff0c;可以运行。 ise EOFError(“No data left in file”) EOFError: No data left in file 到底是因为什么&#xff1f; GPT给的回答&#xff1a; “EOFError: No …

3dMax全球学习资源、资源文件和教程 !

此样例教育教程和学习资源旨在提供使用Autodesk 3ds Max时的计划知识和培训、正确的工作流、流程管理和最佳实践。 您在Autodesk三维设计领域的职业生涯 有关使用3ds Max和Maya在计算机图形领域开始职业生涯的提示&#xff08;包括新的3ds Max和Maya介绍教程&#xff0c;以复…

js reduce求和

let unReadCount resultList.reduce((pre, cur) > {return pre cur.unReadCount}, 0)

自动气象站:无线数据传输、多场景应用

自动气象站能够和环境监控云平台组成气象环境监控系统&#xff0c;能够全天候无人值守地监测气象要素&#xff0c;实现实时监测和数据传输&#xff0c;具有多要素集成、无线数据传输、多场景应用的优势。 一、自动气象站可以全天候不间断地监测空气温度、湿度、大气压力、雨量…

Gin框架---环境搭建

目录 一&#xff1a;MAC安装Go环境二&#xff1a;配置Go相关的环境变量三&#xff1a;设置GO国内代理四&#xff1a;GoLand初始化项目五&#xff1a;安装GIN框架六&#xff1a;Gin框架演示 一&#xff1a;MAC安装Go环境 Go官网地址&#xff1a;https://golang.google.cn/dl/直…

输入部件 QComboBox --组合框/下拉列表

QComboBox 类是 QWidget 类的直接子类&#xff0c;该类实现了一个组合框 一、QComboBox 类中的 属性 QComboBOx 类(组合框)属性速查表属性名说明属性名说明count获取项目数量minimumContentsLength组合框中最少字符数maxCount允许的最大项数maxVisibleItems向用户显示的最大项…

计算机网络第三章——数据链路层(中)

数声风笛离亭晚&#xff0c;君向潇湘我向秦 文章目录 ALOHA协议CSMA协议CSMA/CD协议CSMA/CA协议 总线型和星型都是广播式通信&#xff0c;看一下目的地址是否是我&#xff0c;若是我就接受否则就丢弃&#xff0c;总线型就是若是有一个断了则会影响其他的&#xff0c;型型的就是…

报错:为什么数组明明有内容但打印的length是0

文章目录 一、问题二、分析三、解决1.将异步改为同步2.设置延迟 一、问题 在日常开发中&#xff0c;for 循环遍历调用接口&#xff0c;并将接口返回的值进行拼接&#xff0c;即push到一个新的数组中&#xff0c;但是在for循环内部是可以拿到这个新的数组&#xff0c;而for循环…

接口测试工具开发文档

1 开发规划 1.1 开发人员 角 色 主要职责 负责模块 人员 备注 n xxx模块 xxx 1.2 开发计划 <附开发计划表> 1.3 开发环境和工具 开发工具 工具 作用 Notepad 编辑器 Perl 解释器 2 总体设计 设计思路&#xff1a;因为测试app和server。首先必须…

vue3中使用viewerjs实现图片预览效果

vue3中使用viewerjs实现图片预览效果 1、前言2、实现效果3、在vue3项目中使用viewer.js3.1 安装3.2 在main.js中引入3.3 组件中使用 1、前言 viewer.js是一款开源的图片预览插件&#xff0c;功能十分强大: 支持移动设备触摸事件支持响应式支持放大/缩小支持旋转&#xff08;类…

CPU及并发

2.9G Hz,即每秒进行2.9G次运算(即29亿次) 几个命令 us: 用户使用的cpu sy: 系统(内核)使用的cpu id: idle,即空闲cpu wa: 等待I/O的cpu st: 开虚拟机后会有的一个指标,即虚拟机的cpu使用率 一个进程拥有一整套虚拟地址空间,该进程的所有线程都共享该地址空间. 线程是CPU运算的最…

Docker如何安装seafile

SQLite 方式 要在 Docker 中安装 Seafile&#xff0c;您可以按照以下步骤进行操作&#xff1a; 安装 Docker&#xff1a;确保您的系统上已经安装了 Docker。您可以根据您的操作系统类型&#xff0c;在官方网站上找到适合您系统的 Docker 版本并进行安装。 下载 Seafile 镜像&…

管理类联考——数学——汇总篇——知识点突破——数据分析——计数原理——排列组合——涂色

⛲️ 一、考点讲解 1.题目特征 如果给几种颜色来填涂所给的图形&#xff0c;就是涂色问题。 2.解题方法 可以按照图形逐一依次填涂&#xff0c;也可以按照所用颜色的种数进行分类讨论。 二、考试解读 &#xff08;1&#xff09;涂色问题一般要求相邻的颜色不能相同&#xff0c…