[SpringBoot3]远程访问@HttpExchange

news2024/11/19 17:39:39

六、远程访问@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
    @Bean
    public 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 {
    //注入代理对象
    @Resource
    private TodoService todoService;


    //测试访问todos/1
    @Test
    void testQuery() {
        Todo todo = todoService.getTodoById(1);
        System.out.println("todo = " + todo);
        System.out.println(todo.getTitle());
    }

    //创建资源
    @Test
    void 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);
    }

    //修改资源
    @Test
    void 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);
    }

    //删除资源
    @Test
    void 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 {
    @Resource
    private AlbumsService albumsService;

    @Test
    void 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.单元测试

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

相关文章

C语言入门篇(九)

前言   本篇分享的是部分操作符的概念与用法&#xff0c;从经典例题入手&#xff0c;带你快速了解和掌握。   收录专栏&#xff1a;浅谈C语言 操作符详解下 10. 逗号表达式11. 下标引用、函数调用和结构成员12. 表达式求值12.1 隐士类型转换12.2 算术转换12.3 操作符的属性…

海面漂浮物垃圾识别检测算法

海面漂浮物垃圾识别检测算法通过yolo系列网络框架模型算法&#xff0c;海面漂浮物垃圾识别检测算法一旦识别到海面的漂浮物垃圾&#xff0c;海面漂浮物垃圾识别检测算法立即发出预警信号。目标检测架构分为两种&#xff0c;一种是two-stage&#xff0c;一种是one-stage&#xf…

MFC -- Date Time Picker 控件使用

当前环境&#xff1a;VS2015 Windows 10 //&#xff08;一&#xff09;使用普通函数&#xff0c; 获取当前时间CString strCurrentTime; COleDateTime m_time COleDateTime::GetCurrentTime(); strCurrentTime m_time.Format(_T("%Y-%m-%d %H:%M:%S")); SetDlgIt…

stm32之IIC协议

主要通过两个层面来讲&#xff1a;物理层、协议层。 IIC是一个同步半双工串行总线协议。 一、物理层&#xff08;通信模型&#xff09; 1、最早是飞利浦公司开发的这个协议&#xff0c;最早应用到其产品上去。 2、两线制&#xff08;两根信号线&#xff09; 其中SCL为时钟…

windows下安装mysql

1.下载mysql压缩包 官网下载 我这里选择了最新的版本下载 百度网盘下载&#xff0c;提取码&#xff1a;fu48 2.解压 将下载的压缩文件解压到D:\data\mysql&#xff0c;可自定义位置。 3.配置环境变量 【我的电脑】右键选择【属性】&#xff0c;然后按下图操作&#xff0c;配…

Swing程序设计(2)JFrame窗体

文章目录 前言一、JFrame窗体的介绍 1.创建JFrame窗体2.窗体容器中添加或移除组件二、JFrame窗体的使用 1.JFrame类的常用构造方法2.实例相关语法总结 前言 该文将较为详细地介绍了Swing组件中的JFrame窗体。JFrame窗体是大部分Swing组件的一个载体&#xff0c;这些组件都要在这…

C语言练习7(巩固提升)

C语言练习7 编程题 前言 “芳林新叶催陈叶&#xff0c;流水前波让后波。”改革开放40年来&#xff0c;我们以敢闯敢干的勇气和自我革新的担当&#xff0c;闯出了一条新路、好路&#xff0c;实现了从“赶上时代”到“引领时代”的伟大跨越。今天&#xff0c;我们要不忘初心、牢记…

工作中提高CSS的编写效率,可以多用这三个CSS伪类

:where 基本使用 :where() CSS 伪类函数接受选择器列表作为它的参数&#xff0c;将会选择所有能被该选择器列表中任何一条规则选中的元素。 以下代码&#xff0c;文本都会变成 yellow 颜色 :where(div p) span {color: yellow; }<div class"test-div"><…

如何为你的公司选择正确的AIGC解决方案?

如何为你的公司选择正确的AIGC解决方案&#xff1f; 摘要引言词汇解释&#xff08;详细版本&#xff09;详细介绍1. 确定需求2. 考虑技术能力3. 评估可行性4. 比较不同供应商 代码快及其注释注意事项知识总结 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&…

微信8.0.41更新来了,看看有哪些变化吧

微信给我们带来了极大的方便&#xff0c;无论是日常聊天还是工作沟通&#xff0c;几乎离不开它。 时不时会给我一种熟悉的陌生感。 这个功能&#xff0c;好像我之前是没见过的。 就比如公众号信息流&#xff0c;刷着刷着就会发现&#xff0c;怎么会有看一看的信息推流会突然出现…

C语言控制语句——循环语句

什么是循环 重复执行代码 为什么需要循环 循环的实现方式 whiledo…whilefo while语句 语法格式&#xff1a; while (条件) {循环体…… }需求&#xff1a;跑步5圈 示例代码&#xff1a; #include <stdio.h>int main() {// 需求跑步5圈// 1. 条件变量的定义int i 1;…

golang入门笔记——nginx

文章目录 Nginx介绍Nginx的安装Nginx文件Nginx反向代理负载均衡nginx动静分离URLRewrite防盗链nginx高可用配置安全性Nginx限流Nginx缓存集成Lua脚本OpenRestry Nginx介绍 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;特点是占用内存少&#xff0c;并发能力强&#x…

15-数据结构-二叉树的遍历,递归和非递归

简介&#xff1a; 本文主要是代码实现&#xff0c;二叉树遍历&#xff0c;递归和非递归&#xff08;用栈&#xff09;。主要为了好理解&#xff0c;直接在代码处&#xff0c;加了详细注释&#xff0c;方便复习和后期默写。主要了解其基本思想&#xff0c;为后期熟练应用…

plsql ebs 工作中的简单笔记

工作流中给系统界面发送消息&#xff1a; PROCEDURE wf_notify(p_sender IN VARCHAR2 DEFAULT SYSADMIN,p_receiver IN VARCHAR2,p_subject IN VARCHAR2,p_content_text IN VARCHAR2);PROCEDURE wf_notify(p_sender IN VARCHAR2 DEFAULT SYSADMIN,---发送…

模块和包(Python语言)

目录 一、什么是模块&#xff1f; 二、模块导入方式 2.1方法一&#xff1a; 2.2方法二&#xff1a; 2.3模块导入搜索路径&#xff1a; 2.4模块调用格式&#xff1a; 三、OS模块操作文件 四、模块的操作 4.1模块作用&#xff1a; 4.2模块分类&#xff1a; 4.3魔术变量…

EXSI技术--Exsi资源分割

我们在搭建好环境之后,就类似于有了一个服务器,现在我们就可以对着一个服务器进行一个虚拟化的操作。给不同的用户使用操作。现在,有一个名叫mit的科技企业需要租用服务器用于创建MySQL数据库集群;另外还有一个IECQ的企业需要服务器搭建电商平台。下面我们为这两个企业分割…

进程Start

Linux中的命令解释器和Windows的程序管理器explorer.exe一样地位,都是在用户态下运行的进程 共享变量发生不同进程间的指令交错&#xff0c;就可能会数据出错 进程只作为除CPU之外系统资源的分配单位 CPU的分配单位是线程 每个进程都有自己的独立用户空间 内核空间是OS内核的…

提高工作效率的一键查询和保存大量快递物流信息的技巧

在如今快速发展的电商行业中&#xff0c;物流服务的准确与便捷是保证顺利交付商品的重要环节。为了方便用户追踪物流&#xff0c;固乔快递查询助手应运而生。这款软件不仅能够快速查询快递单号的物流信息&#xff0c;还具备保存查询结果的功能&#xff0c;方便用户随时查看。 首…

光伏电站、变电站、等直流系统电参量测量仪器怎么选型

安科瑞虞佳豪 壹捌柒陆壹伍玖玖零玖叁 应用场景 工作拓扑图 功能 ①对电能参数进行采样计量和监测&#xff0c;逆变器或者能量管理系统&#xff08;EMS&#xff09;与之进行通讯&#xff0c;根据实时功率及累计电能实现防逆流、调节发电量、电池充放电等功能&#xff1b; ②…