[SpringBoot3]远程访问@HttpExchange
六、远程访问@HttpExchange[SpringBoot3]
- 远程访问是开发的常用技术,一个应用能够访问其他应用的功能。SpringBoot提供了多种远程访问的技术。基于HTTP协议的远程访问是最广泛的。
- SpringBoot中定义接口提供HTTP服务。生成的代理对象实现此接口,代理对象实现HTTP的远程访问,需要理解:
- @HttpExchange
- WebClient
WebClient特性
- 我们想要调用其他系统提供的HTTP服务,通常可以使用Spring提供的RestTemplate来访问,RestTemplate是SpringBoot3中引入的同步阻塞式HTTP客户端,因此存在一定性能瓶颈。Spring官方在Spring5中引入了WebClient作为非阻塞式HTTP客户端。
- 非阻塞,异步请求
- 它的响应式编程基于Reactor
- 高并发,硬件资源少
- 支持Java 8 lambdas函数式编程
什么是异步非阻塞
- 异步和同步针对调用者,调用者发送请求,如果等待对方回应之后才去做其他事情,就是同步,如果发送请求之后不等着对方回应就去做其他事情就是异步
- 阻塞和非阻塞针对被调度者,被调度者收到请求后,做完请求任务之后才给出反馈就是阻塞,收到请求之后马上给出反馈然后去做事情,就是非阻塞。
6.1准备工作
- 安装GsonFormat插件,方便json和Bean的转换
6.2声明式HTTP远程服务
- 需求:访问https://jsonplaceholder.typicode.com/提供的todos服务。基于RESTful风格,增删改查。
1.Maven依赖pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--WebClient--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-test</artifactId><scope>test</scope></dependency>
</dependencies>
2.声明Todo数据类
@Data
public class Todo {private Integer userId;private Integer id;private String title;private Boolean completed;
}
3.声明服务接口
public interface TodoService {// 一个方法就是一个远程服务(远程调用)@GetExchange("/todos/{id}")Todo getTodoById(@PathVariable("id") Integer id);//增加资源@PostExchange(value = "/todos/", accept = MediaType.APPLICATION_JSON_VALUE)Todo createTodo(@RequestBody Todo newTodo);//修改资源@PutExchange("/todos/{id}")ResponseEntity<Todo> modifyTodo(@PathVariable Integer id, @RequestBody Todo todo);//删除资源@DeleteExchange("/todos/{sid}")void removeTodo(@PathVariable("sid") Integer id);
}
4.创建HTTP服务代理对象
//proxyBeanMethods = false:多实例对象,无论被取出多少此都是不同的bean实例,在该模式下SpringBoot每次启动会跳过检查容器中是否存在该组件
@Configuration(proxyBeanMethods = false)
public class HttpConfiguration {//创建服务接口的代理对象,基于WebClient@Beanpublic TodoService requestService() {WebClient webClient =WebClient.builder().baseUrl("https://jsonplaceholder.typicode.com").build();//创建代理工厂,设置超时时间HttpServiceProxyFactory proxyFactory =HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).blockTimeout(Duration.ofSeconds(60)).build();//创建某个接口的代理服务return proxyFactory.createClient(TodoService.class);}}
5.单元测试
@SpringBootTest
class Springboot18HttpServiceApplicationTests {//注入代理对象@Resourceprivate TodoService todoService;//测试访问todos/1@Testvoid testQuery() {Todo todo = todoService.getTodoById(1);System.out.println("todo = " + todo);System.out.println(todo.getTitle());}//创建资源@Testvoid testCreateTodo() {Todo todo = new Todo();todo.setId(1222);todo.setUserId(1223);todo.setTitle("事项1");todo.setCompleted(true);Todo res = todoService.createTodo(todo);System.out.println("res = " + res);}//修改资源@Testvoid testModify() {Todo todo = new Todo();todo.setId(1002);todo.setUserId(5002);todo.setTitle("事项2");todo.setCompleted(true);ResponseEntity<Todo> entity = todoService.modifyTodo(2, todo);HttpHeaders headers = entity.getHeaders();System.out.println("headers = " + headers);Todo body = entity.getBody();System.out.println("body = " + body);HttpStatusCode statusCode = entity.getStatusCode();System.out.println("statusCode = " + statusCode);}//删除资源@Testvoid testDelete() {todoService.removeTodo(10);}
}
6.3Http服务接口的方法定义
-
@HttpExchange注解用于声明接口作为HTTP远程服务。在方法、类级别使用。通过注解属性以及方法的参数设置HTTP请求的细节。
-
快捷注解简化不同的请求方式:
- GetExchange
- PostExchange
- PutExchange
- PatchExchange
- DeleteExchange
-
@GetExchange就是@HttpExchange表示的GET请求方式

-
作为HTTP服务接口中的方法允许使用的参数列表

- 接口中方法返回值

6.4组合使用注解
- @HttpExchange、@GetExchange等可以组合使用。
1.创建Albums数据类
@Data
public class Albums {private Integer id;private Integer userId;private String title;
}
2.创建AlbumsService接口
- 接口声明方法,提供HTTP远程服务。
@HttpExchange(url = "https://jsonplaceholder.typicode.com/")
public interface AlbumsService {//查询专辑@HttpExchange(method = "GET",url = "/albums/{id}")Albums getById(@PathVariable Integer id);
}
3.声明代理
@Bean
//创建代理
public AlbumsService albumsService() {WebClient webClient = WebClient.create();HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).blockTimeout(Duration.ofSeconds(60)).build();return proxyFactory.createClient(AlbumsService.class);
}
4.单元测试
@SpringBootTest
public class AlbumsServiceTest {@Resourceprivate AlbumsService albumsService;@Testvoid testQuery() {Albums albums = albumsService.getById(5);System.out.println("albums = " + albums);}
}
6.5Java Record
- 测试Java Record作为返回类型。
创建Albums的Java Record
public record AlbumsRecord(Integer id, Integer userId, String title) {
}
其余步骤一样
6.6定制HTTP请求服务
- 设置HTTP远程的超时时间,异常处理
- 在创建接口代理对象前,先设置WebClient的有关配置。
1.设置超时,异常处理
//定制HTTP服务
@Bean
public AlbumsService albumsService() {//超时HttpClient httpClient = HttpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000)//连接时间.doOnConnected(conn -> {conn.addHandlerLast(new ReadTimeoutHandler(10));//读超时conn.addHandlerLast(new WriteTimeoutHandler(10));//写超时});//设置异常WebClient webClient = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient))//定制 4XX,5XX 的回调函数.defaultStatusHandler(HttpStatusCode::isError, clientResponse -> {System.out.println("WebClient请求异常");return Mono.error(new RuntimeException("请求异常" + clientResponse.statusCode().value()));}).build();HttpServiceProxyFactory proxyFactory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).blockTimeout(Duration.ofSeconds(60)).build();return proxyFactory.createClient(AlbumsService.class);
}
2.单元测试

相关文章:
[SpringBoot3]远程访问@HttpExchange
六、远程访问HttpExchange[SpringBoot3] 远程访问是开发的常用技术,一个应用能够访问其他应用的功能。SpringBoot提供了多种远程访问的技术。基于HTTP协议的远程访问是最广泛的。SpringBoot中定义接口提供HTTP服务。生成的代理对象实现此接口,代理对象实…...
Linux安装ntp并使用阿里云配置ntp服务器
安装 NTP 客户端: 打开终端,以 root 权限执行以下命令来安装 NTP 客户端: sudo zypper install ntp 编辑 NTP 配置文件: 使用文本编辑器打开 NTP 的配置文件 /etc/ntp.conf,例如使用 nano 编辑器: sudo v…...
js常用方法总结
1、slice 和 splice slice表示截取,slice(start,end),不改变原数组,返回新数组。 splice表示删除,splice(start,length,item),会改变原数组,从某个位置开始删除多个元素,并可以插入新的元素。…...
在PHP中安装Composer并管理Vue前端依赖包
系列文章目录 文章目录 系列文章目录前言一、安装Composer二、使用Composer管理PHP依赖包三、使用npm管理Vue前端依赖包总结 前言 在开发Web应用程序时,使用Composer来管理PHP的依赖包和Vue前端的依赖包是一种很常见的做法。Composer是PHP的包管理工具,…...
03-前端基础CSS-第一天
01-CSS层叠样式表导读 目标: 能够说出什么是CSS能够使用CSS基础选择器能够设置字体样式能够设置文本样式能够说出CSS的三种引入方式能够使用Chrome调试工具调试样式 目录: 1.CSS简介2.CSS基础选择器3.CSS字体属性4.CSS文本属性5.CSS引入方式6.综合案…...
多张图片转为pdf怎么弄?
多张图片转为pdf怎么弄?在网络传输过程中,为了避免图片格式文件出现差错,并确保图片的清晰度和色彩不因不同设备而有所改变,常见的做法是将图片转换为PDF格式。然而,当涉及到多张图片时,逐一转换将会变得相…...
jdk新版本特性
JDK8,JDK11,JDK17,JDK21及中间版本主要更新特性_jdk重要版本_ycsdn10的博客-CSDN博客 Java 20 新特性概览 | JavaGuide(Java面试 学习指南)...
进程Start
Linux中的命令解释器和Windows的程序管理器explorer.exe一样地位,都是在用户态下运行的进程 共享变量发生不同进程间的指令交错,就可能会数据出错 进程只作为除CPU之外系统资源的分配单位 CPU的分配单位是线程 每个进程都有自己的独立用户空间 内核空间是OS内核的…...
SpringCloud学习笔记(六)_Ribbon服务调用
Ribbon介绍 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具 Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时、重试等。简单的说,就是…...
系统架构设计师考试论文:论无服务器架构及其应用
近年来,随着信息技术的迅猛发展和应用需求的快速更迭,传统的多层企业应用系统架构面临越来越多的挑战,已经难以适应这种变化。在这一背景下,无服务器架构(ServliessArchitecture)逐渐流行,它强调业务逻辑由事件触发&am…...
linux下安装Mycat
1 官网下载mycat 官方网站: 上海云业网络科技有限公司http://www.mycat.org.cn/ github地址: MyCATApache GitHubMyCATApache has 34 repositories available. Follow their code on GitHub.https://github.com/MyCATApache 2 Mycat安装 1 把MyCat…...
OpenCV(八):图像二值化
目录 1.固定值二值化 2.自适应阈值二值化 3.Android JNI完整代码 1.固定值二值化 固定阈值二值化是OpenCV中一种简单而常用的图像处理技术,用于将图像转换为二值图像。在固定阈值二值化中,像素值根据一个预定义的阈值进行分类,大于阈值的…...
《Flink学习笔记》——第十一章 Flink Table API和 Flink SQL
Table API和SQL是最上层的API,在Flink中这两种API被集成在一起,SQL执行的对象也是Flink中的表(Table),所以我们一般会认为它们是一体的。Flink是批流统一的处理框架,无论是批处理(DataSet API&a…...
电脑提示缺少d3dx9_43.dll的问题及5个解决方法
大家好!今天,我将和大家分享一个电脑提示缺少d3dx9_43.dll的问题及其解决方法。这个问题可能会影响到我们在使用电脑时的一些功能,所以掌握这个解决方法对我们来说是非常有帮助的。 首先,我们来了解一下什么是d3dx9_43.dll。d3dx9…...
Linux stat 命令及示例
介绍 该stat命令打印有关文件和文件系统的详细信息。该工具提供有关所有者是谁、修改日期、访问权限、大小、类型等信息。 该实用程序对于故障排除、在更改文件之前获取有关文件的信息以及例行文件和系统管理任务至关重要。 本文stat通过实际示例解释了有关 Linux 命令的所有…...
06-基础例程6
基础例程6 01、WIFI实验—WebServer 实验介绍 连接路由器上网是我们每天都做的事情,日常生活中只需要知道路由器的账号和密码,就可以使用手机或电脑连接到路由器,然后上网。 连接路由器,将ESP32的IP地址等信息通过shell…...
【附安装包】Eplan2022安装教程
软件下载 软件:Eplan版本:2022语言:简体中文大小:1.52G安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.5GHz 内存4G(或更高)下载通道①百度网盘丨64位下载链接:https://pan.baidu.co…...
大数据-玩转数据-Flink窗口
一、Flink 窗口 理解 在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击…...
【python爬虫】—豆瓣电影Top250
豆瓣电影Top250 豆瓣榜单简介需求描述Python实现 豆瓣榜单简介 豆瓣电影 Top 250 榜单是豆瓣网站上列出的评分最高、受观众喜爱的电影作品。这个榜单包含了一系列优秀的影片,涵盖了各种类型、不同国家和时期的电影。 需求描述 使用python爬取top250电影ÿ…...
【跟小嘉学 Rust 编程】十五、智能指针
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
