Springboot3声明式客户端

简介

Spring Framework 6 和 Spring Boot 3 引入了一些新的特性和改进,以简化 HTTP API 的消费。它允许开发者通过声明式接口来定义对外部 HTTP API 的调用。其中开发者只需要定义接口和方法签名,而具体的实现细节由框架自动生成。

这个特性通常被称为 "声明式 REST 客户端" 或者 "Feign 客户端"(如果使用的是 Netflix Feign 库),在 Spring 生态中也得到了支持。当您使用这样的声明式客户端时,您将创建一个接口,并使用注解来指定每个方法对应哪个 HTTP 路径、请求类型(GET, POST, PUT 等)、路径参数、查询参数等信息。然后,Spring 框架会基于这些接口和方法自动创建代理实例,处理所有的 HTTP 通信细节。

添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

测试环境ChuckNorris

https://api.chucknorris.io/ 是 Chuck Norris Facts API 的地址,它提供了一个非正式的、用于娱乐目的的接口来获取关于 Chuck Norris 的趣闻。这个 API 可以用来展示如何与 RESTful 服务进行交互,非常适合用作学习和演示 HTTP 请求和响应处理。

Chuck Norris Jokes Api

测试返回结果

声明式接口

在Spring框架中,特别是使用Spring WebFlux或Spring WebClient时,声明式HTTP客户端接口为开发者提供了一种简洁且类型安全的方式来定义与远程服务交互的方法。通过使用这些注解,您可以轻松地指定要执行的HTTP方法、端点以及如何处理响应。以下是对您提到的内容的详细解释和扩展:

使用ResponseEntity 和 反应式类型

当涉及到HTTP接口方法的返回类型时,如果您想要访问HTTP头和状态码,可以使用ResponseEntity<T>,其中T是响应体的类型。对于反应式编程模型(如WebFlux),还支持使用Mono<ResponseEntity<T>>Flux<ResponseEntity<T>>来处理异步响应。

Mono<ResponseEntity<MyResponseType>> getJoke() {return webClient.get().uri("/jokes/random").retrieve().toEntity(MyResponseType.class);
}

HTTP 方法相关的注解

为了简化对不同HTTP方法的调用,Spring提供了多个注解用于标注接口方法,使得代码更加清晰易读。以下是常用的几个注解及其用途:

  • @GetExchange: 用于HTTP GET请求。

    @GetExchange("/jokes/random")
    Mono<MyResponseType> getRandomJoke();
  • @PostExchange: 用于HTTP POST请求。表示请求有效载荷的HTTP接口方法参数应该使用@RequestBody注解进行标注。

    @PostExchange("/items")
    Mono<Item> createItem(@RequestBody Item item);
  • @PutExchange: 用于HTTP PUT请求。

    @PutExchange("/items/{id}")
    Mono<Void> updateItem(@PathVariable String id, @RequestBody Item item);
  • @PatchExchange: 用于HTTP PATCH请求。

    @PatchExchange("/items/{id}")
    Mono<Item> partiallyUpdateItem(@PathVariable String id, @RequestBody ItemUpdateRequest request);
  • @DeleteExchange: 用于HTTP DELETE请求。

    @DeleteExchange("/items/{id}")
    Mono<Void> deleteItem(@PathVariable String id);
  • @HttpExchange: 最通用的注解。上述所有特定于HTTP方法的注解都是基于此元注解创建的。它允许更灵活地配置URL和HTTP方法。

    @HttpExchange(url = "/jokes/random", method = "GET")
    Mono<MyResponseType> getRandomJokeUsingHttpExchange();

示例

Controller

package com.coderlk.restdemo.controller;import com.coderlk.restdemo.client.RestDemo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@Slf4j
public class RestDemoController {@ResourceRestDemo client;@GetMapping("/")public String remote(){log.info("ChuckNorrisController.remote start random: {}", client.getRandomQuote());log.info("Categories: {}", client.getCategories());log.info("Joke from money category: {}", client.getQuoteFromCategory("money"));return "SUCCESS";}
}

 Client

package com.coderlk.restdemo.client;import com.coderlk.restdemo.vo.RestDemoVO;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.HttpExchange;import java.util.List;@HttpExchange(url = "/jokes")
public interface RestDemo {@HttpExchange(url = "/random", method = "GET")RestDemoVO getRandomQuote();@GetExchange("/random")RestDemoVO getQuoteFromCategory(@RequestParam("category") String category);@GetExchange("/categories")List<String> getCategories();
}

Config

package com.coderlk.restdemo.config;import com.coderlk.restdemo.client.RestDemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;@Configuration
public class AppConfig {@Beanpublic RestDemo chuckNorrisClient() throws Exception {WebClient webClient = WebClient.builder().baseUrl("https://api.chucknorris.io/").build();HttpServiceProxyFactory httpServiceProxyFactory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build();return httpServiceProxyFactory.createClient(RestDemo.class);}
}

VO

package com.coderlk.restdemo.vo;import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;@Data
public class RestDemoVO {private String value;private String url;private String id;@JsonProperty("icon_url")private String iconUrl;@JsonProperty("created_at")private String createdAt;@JsonProperty("updated_at")private String updatedAt;
}

Application

package com.coderlk.restdemo;import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@Slf4j
public class RestDemoApplication {public static void main(String[] args) {SpringApplication.run(RestDemoApplication.class, args);}}

application.properties

server.port=80

测试

2024-12-23T09:42:16.253+08:00  INFO 87005 --- [p-nio-80-exec-3] c.c.c.r.controller.RestDemoController    : ChuckNorrisController.remote start random: RestDemoVO(value=Mick Jagger: "oh you can't always get what you waaaannt." Chuck Norris "Yes I can.", url=https://api.chucknorris.io/jokes/NqcgUOhxQH2cf7oWrvTj1Q, id=NqcgUOhxQH2cf7oWrvTj1Q, iconUrl=https://api.chucknorris.io/img/avatar/chuck-norris.png, createdAt=2020-01-05 13:42:22.089095, updatedAt=2020-01-05 13:42:22.089095)
2024-12-23T09:42:16.640+08:00  INFO 87005 --- [p-nio-80-exec-3] c.c.c.r.controller.RestDemoController    : Categories: [animal, career, celebrity, dev, explicit, fashion, food, history, money, movie, music, political, religion, science, sport, travel]
2024-12-23T09:42:17.021+08:00  INFO 87005 --- [p-nio-80-exec-3] c.c.c.r.controller.RestDemoController    : Joke from money category: RestDemoVO(value=Chuck Norris is the true Sultan of Swing. He also gets his money for nothing, and his chicks for free., url=https://api.chucknorris.io/jokes/L1GsWHngRoSW1UPXidGQgg, id=L1GsWHngRoSW1UPXidGQgg, iconUrl=https://api.chucknorris.io/img/avatar/chuck-norris.png, createdAt=2020-01-05 13:42:28.420821, updatedAt=2020-05-22 06:16:41.133769)

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

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

相关文章

信贷域——互联网金融体系

摘要 本文介绍了互联网金融的概念、特征、发展阶段和生态。互联网金融是互联网与金融结合的新兴模式&#xff0c;以大数据、云计算为基础&#xff0c;实现资金融通和支付。发展经历了技术支持、业务领域深入到金融业务领域三个阶段。互联网金融生态包括互联网支付、P2P网络借贷…

精通Redis

目录 1.NoSQL 非关系型数据库 2.Redis 3.Redis的java客户端 4.Jedis 4.1Jedis快速入门 4.2Jedis连接池及使用 5.SpringDataRedis和RedisTemplate 6.SpringDataRedis快速入门 7.RedisSerializer 1.NoSQL 非关系型数据库 基础篇-02.初始Redis-认识NoSQL_哔哩哔哩_bilib…

LabVIEW水泵性能测试系统

在现代工业应用中&#xff0c;水泵作为一种广泛使用的流体输送设备&#xff0c;其性能的可靠性对整个生产系统的稳定运行至关重要。通过LabVIEW软件配合专业硬件设备&#xff0c;设计了一套水泵性能测试系统&#xff0c;实现对各类水泵的综合性能测试与分析&#xff0c;提升水泵…

2.利用docker进行gitlab服务器迁移

一、Docker安装 安装Ubuntu 22.04.3 LTS \n \l 1、旧版本安装包清理 sudo apt-get remove docker docker-engine docker.io containerd runc当你卸载Docker时&#xff0c;存储在/var/lib/docker/中的图像、容器、卷和网络不会自动删除。如果你想从一个干净的安装开始&#x…

无人零售 4G 工业无线路由器赋能自助贩卖机高效运营

工业4G路由器为运营商赋予 “千里眼”&#xff0c;实现对贩卖机销售、库存、设备状态的远程精准监控&#xff0c;便于及时补货与维护&#xff1b;凭借强大的数据实时传输&#xff0c;助力深度洞察销售趋势、优化库存、挖掘商机&#xff1b;还能远程升级、保障交易安全、快速处理…

zabbix监控山石系列Hillstone监控模版(适用于zabbix7及以上)

监控项&#xff1a; 触发器&#xff1a; 监控数据如下&#xff1a;

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo 前言摘要引言Task 相关工作方法SDM-UniPS预处理尺度不变的空间光特征编码器像素采样变压器的非局部交互 PS-Mix数据集 实验结果训练细节评估和时间&#xff1a; 消融实验定向照明下的评估没有对…

【MySQL】7.0 入门学习(七)——MySQL基本指令:帮助、清除输入、查询等

1.0 help &#xff1f; 帮助指令&#xff0c;查询某个指令的解释、用法、说明等。详情参考博文&#xff1a; 【数据库】6.0 MySQL入门学习&#xff08;六&#xff09;——MySQL启动与停止、官方手册、文档查询 https://www.cnblogs.com/xiaofu007/p/10301005.html 2.0 在cmd命…

低代码开源项目Joget的研究——基本概念和应用

大纲 1. 基本概念1.1 Form1.1.1 Form1.1.1.1 概述1.1.1.2 主要特点和用途1.1.1.3 创建和使用 Form1.1.1.4 示例 1.1.2 Section1.1.2.1 概述1.1.2.2 主要特点和用途1.1.2.3 示例 1.1.3 Column1.1.4 Field1.1.5 示例 1.2 Datalist1.2.1 Datalist1.2.1.1 主要特点和用途1.2.1.2 创…

单机游戏《野狗子》游戏运行时提示dbghelp.dll缺失是什么原因?dbghelp.dll缺失要怎么解决?

《野狗子》游戏运行时提示dbghelp.dll缺失&#xff1a;原因与解决方案 在畅游《野狗子》这款引人入胜的游戏世界时&#xff0c;突然遭遇“dbghelp.dll缺失”的错误提示&#xff0c;无疑会给玩家的探险之旅蒙上一层阴影。作为一名深耕软件开发领域的从业者&#xff0c;我深知此…

Marscode AI辅助编程

直接使用Marscode的云服务来开发&#xff0c;也是很方便的&#xff0c;不用担心配置环境的问题&#xff0c;很适合初步学习&#xff0c;在任何设备都能开发。 番茄钟 请你基于html、tailwind css和javascript&#xff0c;帮我设计一个“番茄时钟”。要求UI简洁美观大方&#x…

使用Vue的props进行组件传递校验时出现 Extraneous non-props attributes的解决方案

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;WebStorm 目录 出现错误的情况 报错&#xff1a; 代码&#xff1a; 报错截图 原因分析 解决方案 方法一 方法二 出现错误的情况 以下是我遇到该错误时遇到的报错和代码&…

ffmpeg之显示一个yuv照片

显示YUV图片的步骤 1.初始化SDL库 目的&#xff1a;确保SDL库正确初始化&#xff0c;以便可以使用其窗口、渲染和事件处理功能。操作&#xff1a;调用 SDL_Init(SDL_INIT_VIDEO) 来初始化SDL的视频子系统。 2.创建窗口用于显示YUV图像&#xff1a; 目的&#xff1a;创建一个…

iDP3复现代码模型训练全流程(一)——train_policy.sh

iDP3 核心脚本包括三个&#xff1a;deploy_policy.sh、vis_dataset.sh、train_policy.sh&#xff0c;分别代表了部署、预处理和训练&#xff0c;分别作为对应 py 脚本的参数设置前置环节 训练环节仅需运行指令&#xff1a; # 3d policy bash scripts/train_policy.sh idp3 gr1…

链原生 Web3 AI 网络 Chainbase 推出 AVS 主网, 拓展 EigenLayer AVS 应用场景

Chainbase AVS 主网的正式上线&#xff0c;正在将 Chainbase 不同的层进行深入的串联&#xff0c;为 Chainbase 数据网络带来了验证和处理方面的应用与拓展的能力&#xff0c;并成为数据体系全面启动的新契机。 在 12 月 4 日&#xff0c;链原生的 Web3 AI 数据网络 Chainbase …

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

Jenkins 任意文件读取(CVE-2024-23897)修复及复现

Jenkins任意文件读取漏洞CVE-2024-23897修复及复现 漏洞详情影响范围漏洞复现修复建议 Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行…

智慧农业云平台与水肥一体化:道品科技引领农业现代化新潮流

在当今科技飞速发展的时代&#xff0c;农业也正经历着一场深刻的变革。智慧农业云平台和水肥一体化技术的出现&#xff0c;为农业生产带来了前所未有的机遇和挑战。 一、智慧农业云平台&#xff1a;农业生产的 “智慧大脑” 智慧农业云平台就像是农业生产的 “智慧大脑”&…

C++--------内存结构

C内存结构 程序内存分区&#xff1a; 栈区&#xff08;Stack&#xff09;&#xff1a;由编译器自动分配和释放&#xff0c;用于存放函数的参数值、局部变量等。其操作方式类似于数据结构中的栈&#xff0c;先进后出。例如&#xff0c;在函数调用时&#xff0c;函数内部的局部变…

f(f(x))=x^2 -11x+36, 求f(6)的值,

偶然看到的一个题目&#xff0c;一时兴起&#xff0c;做了一下。题目如下 简单粗暴的思路是待定系数法&#xff0c;盲猜f(x)是个2次函数&#xff0c;令f(x)ax^2bxc ,带入原式&#xff0c;发现矛盾&#xff08;计算略&#xff09;就想放弃了。 忽然看到如果带入6 的话&#xf…