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命…

网络基础知识--4

什么是PBR? 1.定义 PBR&#xff08;Policy - Based Routing&#xff09;即策略路由。它是一种网络技术&#xff0c;允许网络管理员根据自己定义的策略来转发数据包&#xff0c;而不是仅仅依赖于传统的基于目的地址的路由方式。通过 PBR&#xff0c;网络管理员可以灵活地控制…

2024最新鸿蒙开发面试题合集-HarmonyOS NEXT Release(API 12 Release)

1. HarmonyOS应用打包后的文件扩展名是? 打包后的文件扩展名为.hap&#xff08;HarmonyOS Ability Package&#xff09;&#xff0c;这是HarmonyOS应用的标准包格式 2. 页面和自定义组件生命周期有哪些? 页面和自定义组件生命周期说明 有Entry装饰器的component组件的生命…

低代码开源项目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; 报错截图 原因分析 解决方案 方法一 方法二 出现错误的情况 以下是我遇到该错误时遇到的报错和代码&…

后端-redis

Redis RedisString类型String类型的常用命令 Hash类型Hash类型的常用命令 List类型List类型的常用命令 Set类型Set类型的常用命令 SortedSet类型SortedSet类型的常用命令 Redis序列化缓存更新策略缓存穿透缓存雪崩缓存击穿 Redis Redis是一个key-value的数据库&#xff0c;key…

Android 代码模式的理解

定义&#xff1a;给目标对象提供一个代理对象&#xff0c;并由代理对象控制目标对象的引用 目的&#xff1a;通过引入代理的方式来间接访问目标对象&#xff0c;防止直接访问目标对象给系统带来不确定的复杂性 静态代理&#xff1a;编译时就确定了被代理的类是哪一个动态代理&…

基于卷积神经网络融合Inception模块的人脸识别

&#x1f472;&#x1f472;作者主页&#xff1a;&#x1f517;杰森的博客 &#x1f4d2;&#x1f4d2;本文摘要&#xff1a;基于卷积神经网络融合Inception模块的人脸识别&#xff0c;原理分享 &#x1f496;&#x1f496;如果本文帮助到你的话&#xff0c;还请各位小伙伴&…

ffmpeg之显示一个yuv照片

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

php的线程安全与非线程安全版本的区别

PHP的线程安全&#xff08;Thread Safe&#xff0c;简称TS&#xff09;与非线程安全&#xff08;Non-Thread Safe&#xff0c;简称NTS&#xff09;版本主要在多线程环境下的行为特性、性能、以及适用场景上存在差异。以下是两者的详细对比&#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…