Vert.x Java开发指南——第六章 与第三方的Web服务集成

CompletableFuture执行线程的一次研究 在研究vertx线程模型的时候我开始注意到在vertx内部提供给开发者的多数异步api中用到了CompletableFuture或者Promise或者Future。以前也用过CompletableFuture和Futrue等,但当时没有想过它执行时的线程情况,于是写了个测试类用于了解它: public class VertxTest { Logger logger = LoggerFacto 阅读详情

第六章 与第三方的Web服务集成

版权声明:本文为博主自主翻译,转载请标明出处。 https://blog.youkuaiyun.com/elinespace/article/details/80558824

相应代码位于本指南仓库的step-5目录下。

现代应用很少位于孤岛之上,因为它们需要与其它(分布式)应用和服务集成。集成通常采用API实现,这些API通过多功能的HTTP协议公开。

本章展示了如何使用Vert.x的HTTP客户端API与第三方Web服务集成。

6.1 场景:备份到GitHub Gist

GitHub Gist服务(https://gist.github.com/)因分享代码片段到全世界而广受欢迎。其它服务可以使用它,一个例子就是Medium publishing platform,在该平台,Gist链接使代码片段可以嵌入到出版物内部。

GitHub公开了一个详细的API用于获取、创建、更新和删除Gist。该API使用以http://api.github.com/开始的HTTPS端点和JSON荷载。

虽然许多操作使用OAuth认证从客户端获取授权,但在匿名的情况下创建Gist是可能的。我们将利用这个特征备份我们的wiki页面为Gist。

一个新的按钮将被添加到wiki index页面:

这里写图片描述

点击backup按钮将触发一个Gist的创建操作:

这里写图片描述

备份Gist由每个Wiki页面一个文件组成,内容是未加工的Markdown文本:

这里写图片描述

6.2 更新数据库服务

在我们深入Web客户端API,并执行到其它服务的HTTP请求之前,我们需要更新数据库服务API,一次性获取所有的Wiki页面。这相当于添加下面的SQL查询到db-queries.properties:

all-pages-data=select * from Pages

添加一个新的方法到WikiDatabaseService接口:

@Fluent
WikiDatabaseService fetchAllPagesData(Handler<AsyncResult<List<JsonObject>>> resultHandler);

WikiDatabaseServiceImpl中的实现如下:

@Override
public WikiDatabaseService fetchAllPagesData(Handler<AsyncResult<List<JsonObject>>> resultHandler) {
    dbClient.query(sqlQueries.get(SqlQuery.ALL_PAGES_DATA), queryResult -> {
        if (queryResult.succeeded()) {
            resultHandler.handle(Future.succeededFuture(queryResult.result().getRows()));
        } else {
            LOGGER.error("Database query error", queryResult.cause());
            resultHandler.handle(Future.failedFuture(queryResult.cause()));
        }
    });
    return this;
}

6.3 Web客户端API

Vert.x核心库在vertx上下文对象提供了一个createHttpClient方法。io.vertx.core.http.HttpClient实例提供了底层的方法用于执行所有类型的HTTP请求,并对协议和事件流进行细粒度控制。

Web客户端API提供了一个简单的外观,尤其是简化了荷载的编组与解组。该API以一种新的依赖的形式出现:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web-client</artifactId>
    <version>${vertx.version}</version>
</dependency>

以下是来自一个单元测试的样例用法。它启动一个HTTP服务器,然后使用Web客户端API执行一个HTTP GET请求,检查到服务器的请求是否成功:

@Test
public void start_http_server(TestContext context) {
    Async async = context.async();
    vertx.createHttpServer()
            .requestHandler(req -> req.response().putHeader("Content-Type", "text/plain").end("Ok"))
            .listen(8080,context.asyncAssertSuccess(server -> {
                WebClient webClient = WebClient.create(vertx);
                webClient.get(8080, "localhost", "/").send(ar -> {
                    if (ar.succeeded()) {
                        HttpResponse<Buffer> response = ar.result();
                        context.assertTrue(response.headers().contains("Content-Type"));
                        context.assertEquals("text/plain",response.getHeader("Content-Type"));
                        context.assertEquals("Ok", response.body().toString());
                        webClient.close();
                        async.complete();
                    } else {
                        async.resolve(Future.failedFuture(ar.cause()));
                    }
                });
            }));
}

6.4 创建匿名的Gist

我们首先创建一个Web客户端对象,然后向Gist API发出HTTP请求:

webClient = WebClient.create(vertx, new WebClientOptions()
    .setSsl(true)
    .setUserAgent("vert-x3"));

由于请求使用HTTPS构造,我们需要配置Web客户端支持SSL。

 

GitHub API需要一个有效的User-Agent头,并请求一个GitHub账号或者组织标识。我们复写默认的User-Agent为vert-x3,但是你可以选择你自己的值替代。

我们接下来修改HttpServerVerticle类中的Web路由配置,为触发备份添加一个新的路由:

router.get("/backup").handler(this::backupHandler);

该处理器的代码如下:

private void backupHandler(RoutingContext context) {
    dbService.fetchAllPagesData(reply -> {
        if (reply.succeeded()) {
            JsonObject filesObject = new JsonObject();
            JsonObject gistPayload = new JsonObject() ①
                .put("files", filesObject)
                .put("description", "A wiki backup")
                .put("public", true);
            reply.result().forEach(page -> {
                JsonObject fileObject = new JsonObject(); ②
                filesObject.put(page.getString("NAME"), fileObject);
                fileObject.put("content", page.getString("CONTENT"));
            });
            webClient.post(443, "api.github.com", "/gists") ③
                .putHeader("Accept", "application/vnd.github.v3+json") ④
                .putHeader("Content-Type", "application/json")
                .as(BodyCodec.jsonObject()) ⑤
                .sendJsonObject(gistPayload, ar -> { ⑥
                    if (ar.succeeded()) {
                        HttpResponse<JsonObject> response = ar.result();
                        if (response.statusCode() == 201) {
                            context.put("backup_gist_url", response.body().getString("html_url")); ⑦
                            indexHandler(context);
                        } else {
                            StringBuilder message = new StringBuilder()
                                .append("Could not backup the wiki: ")
                                .append(response.statusMessage());
                            JsonObject body = response.body();
                            if (body != null) {
                                message.append(System.getProperty("line.separator"))
                                        .append(body.encodePrettily());
                            }
                            LOGGER.error(message.toString());
                            context.fail(502);
                        }
                    } else {
                        Throwable err = ar.cause();
                        LOGGER.error("HTTP Client error", err);
                        context.fail(err);
                    }
                });
            } else {
                context.fail(reply.cause());
            }
    });
}

① Gist创建的请求载荷(payload)是一个JSON文档,如GitHub API文档(https://developer.github.com/v3/gists/#create-a-gist)中所描述。

② 每个文件是载荷files对象中的一条记录,title为键,值为文本。

③ web客户端需要发出一个POST请求到443端口(HTTPS),路径必须为/gists。

④ 请求中强制包含一个Accept头,使用application/vnd.github.v3+json MIME类型,否则请求会失败。在下一行中指定有效载荷是JSON对象也很重要。

⑤ BodyCodec类提供了一个助手,明确规定将响应直接转换为Vert.x的JsonObject实例。它也可以使用BodyCodec#json(Class)方法,将JSON数据将映射为一个Java对象,类型为T(底层使用了Jackson数据映射)。

⑥ sendJsonObject是一个助手方法,用于触发JSON载荷的HTTP请求。

⑦ 当成功时,我们可以通过JSON数据(html_url键)来获得新建Gist的用户友好的URL。

Ragflow技术栈分析及二次开发指南 Ragflow是目前团队化部署大模型+RAG的优质方案,不过其仍不适合直接部署使用,本文将从实际使用的角度,对其进行二次开发 阅读详情

相关推荐

【BAT32G113-仿真器及脱机烧录器教程-A3-2024/9/19】

提示:此壁纸收集于互联网,如有侵权,请联系作者!今日下班,闲来无事,就与生活中在乎的人闲日常,互相彼此增进一些友谊或爱意情愫!在座的朋友看到这里,有时间,抽抽空,多多联系一下,身边重要的人哟!四种指示灯和一个按钮:MODE->代表红色POWER->代表黄色ACTIVE->代表蓝色STATUS->代表XX(不记得了)黑色按钮:按键上电,会进入升级模式,这里我们一般默认不需要改变!仿真工具-ICE8-PRO介绍隶属于产品分支里。烧写工具-CMS-WRITER8 LITE介绍点击。

星新计划的博客 8264

Vert.x Java开发指南——第四章 重构为Vert.x服务

第四章 重构为Vert.x服务 与我们最早的实现相比,前面的重构已经是向前一大步,因为我们提取出了独立且可配置的Verticle,并且在事件总线之上使用异步消息进行链接。我们还看到,我们可以同时部署一个指定Verticle的几个实例,以便更好地处理负载以及更好地利用CPU内核。 在这一节,我们将看到如何设计和使用Vert.x服务。服务的主要优势是,它定义了一个接口用于执行Verticle公开的...

边城白衣的博客 3388

USB3.0/3.1信号完整性分析仿真

• 1.了解USB3.0通路的互连关系,解读原理图接口电路和PCB的互连电路。对USB布线的通路及阻抗进行检查和分析。 • 2.使用USB3.0实例文件提取互连线的S参数,选择SSRX+,SSRX-,SSTX+,SSTX-,D+,D-组的互连线,使用PowerSI,Clarity,3DFEM等工具提起关键网络的S参数。提取S参数以后需要分析S参数的互连特征,对S参数的结果开展评价。 • 3.使用SYSTEM SI USB3 Compliance工程向导模型,建立USB仿真实例框架,在框架BOLCK中带入S参

小猪配齐电子设计 1万+

vertx 异步编程指南 step3-重构vert.x服务

前言:这一节主要讲把数据库暴露为异步rpc接口,然后调用, 比发送到event bus消息要方便使用一些。和第一节相比,第二节向前迈了很大一步,我们使用异步消息调用event bus上的独立的可配置的verticle.我们也看到了可以部署多个实例配置负载均衡和充分的利用多核cpu.在本节,我们将学习如何设计和使用vert.x 服务。service的主要优势是他定义了一个接口来执行verticle暴...

zyydecsdn的博客 2305

Pyrosim进阶指南:从隧道火灾模拟到复杂通风策略分析

本文深入探讨Pyrosim在隧道火灾模拟与通风策略分析中的高级应用。从精确几何建模到火源参数设置,再到通风系统的量化分析,详细介绍了如何利用Pyrosim优化隧道安全设计。特别强调了临界风速验证、横向通风配置及结果可视化技巧,为工程师提供实用的进阶指南。

weixin_30644369的博客 138

手把手教你用LTspice仿真TVS二极管:从选型验证到波形分析全流程

本文详细介绍了如何使用LTspice仿真TVS二极管,从选型验证到波形分析的全流程。通过搭建仿真环境、核心参数验证和系统级防护策略,帮助工程师低成本评估TVS性能,优化电路设计。特别适用于电源设计和接口防护领域,提升工作效率和设计准确性。

weixin_29234239的博客 646

vert.x框架学习笔记

摘要Vert.x最大的特点就在于异步(底层基于Netty),通过事件循环(EventLoop)来调起存储在异步任务队列(CallBackQueue)中的任务,大大降低了传统阻塞模型中线程对于操作系统的开销。因此相比较传统的阻塞模型,异步模型能够很大层度的提高系统的并发量。Vert.x除了异步之外,还提供了非常多的吸引人的技术,比如EventBus,通过EventBus可以非常简单的实现分布式消息,进而为分布式系统调用,微服务奠定基础。

zwj1030711290的优快云 3624

Sigrity Power Tree如何生成电源树操作指导

Sigrity Power Tree可以方便地生成电源树,仅需要网表文件就能将系统的电源树直观的显示出来,生成的电源树文件可以用Power DC,optimizePI进行直流和交流仿真,下面介绍如何生成电源树。Base on [Device_TYPE and VALUE]就是识别网表中器件的Device_TYPE作为power tree中的模型的名字。Allegro layout netlist file,就是从Allegro layout文件中输出的netlist第三方网表文件。如何生成电源树操作指导。

weixin_54787054的博客 1534

vertx和springboot整合案例

项目结构: 依赖: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/

点点的博客 2559

AUTOSAR CP R18-10 架构总览与导航

AUTOSAR CP R18-10 架构总览 本文档系统整理了AUTOSAR CP R18-10版本的199篇技术规范,涵盖7大架构层级: 应用层(15篇):包含车身舒适、底盘控制、HMI、安全系统、动力系统等AI应用 RTE(1篇):虚拟功能总线规范 服务层(159篇):细分为系统服务(OS/ECU管理/加密)、存储服务、通信服务(CAN/LIN/Ethernet) ECU抽象层(20篇):I/O与通信硬件抽象 MCAL(41篇):微控制器驱动层 复杂驱动(14篇):CDD设计与SPAL支撑 规范模板(2

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 721

基于simulink的自动紧急制动系统(AEB)的功能验证

本文手把手指导使用Simulink构建自动紧急制动系统(AEB)模型,通过五个关键步骤完成功能验证:1)搭建车辆动力学模型;2)设计雷达传感器模型;3)开发基于碰撞时间(TTC)的决策逻辑;4)设计标准化测试场景;5)进行仿真分析。重点讲解了AEB的多级触发机制(预警、辅助制动、自动制动)和核心指标验证方法,包括制动时机判断、减速度性能等。通过典型场景仿真,展示了AEB如何在2.5秒TTC触发预警,1.2秒TTC启动自动制动,有效避免碰撞。文章还展望了行人AEB、传感器融合等进阶研究方向,为自动驾驶安全系统

amy_mhd的博客 267

Vert.x 4 异步编程 - Futures 和 Promises

但java程序员,最习惯的是链式调用,我们自然会想,在 Vert.x中有没有跟JavaScript的Promise相类似的机制,可以将lambda表达式转换成链式调用呢? 用Future+ Promise就将参数中的lambda表达式变成返回值,从而实现链式调用

白石的专栏 2309

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Vert.x(vertx) Web开发-路由

在Vert.x 创建HTTP服务 中我们已经创建了一个简单的HttpServer,但这个HttpServer比较低级,对于请求参数解析、Session等常用功能都需要我们通过编码实现,也就是要重复造轮子,非常不方便。 Vert.x提供了Web开发组件vertx-web,提供了一堆Web开发中常用的功能。比如参数封装,路由,国际化,认证和授权,session和cookie以及模板等,可以非常方便的...

happyfly的博客 2万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

tomcat和vert.x服务器nio模型对比

大家知道服务器BIO模式下,每个请求都要创建一个线程,而线程的内存和上下文切换的开销都比较大。所以在BIO模式下,高并发的支持比较差。NIO通过多路复用和eventloop,减少线程开销,从而提高并发量。 vert.x由于其轻量,良好的高并发能力被熟知。 而一些同学会有一些误区,认为tomcat并发能力比vert.x要差。事实上,springboot集成的tomcat,缺省的运行模式就是NIO。从原理上看,并发能力并不差。 Vert.x 服务器nio线程模型 – 一个acceptor线程,用来监听客户端连接

lgleje的博客 1709

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

vertx的Future设计

异步痛点 1.回调地狱(CallBack hell) ; 解决方式 Promise 或 Future 2.执行异步后的结果如何回调currentThread ; 解决方式 Context 设计 3.如何处理依赖多异步的result进行逻辑 ; 解决方案 CompositeFuture JDK的lib库 Callable和Future 问题 Callable任务可以返回结果,返回的结果可以...

weixin_30325487的博客 1263

java之Vertx.web开发

Vertx开发web server

hyly_zhard的博客 1234

vertx 异步编程指南 step5-与第三方Web服务集成

现代应用程序很少生活在孤立的岛上,因为它们需要与其他(分布式)应用程序和服务集成。通常使用通过HTTP协议公开的API来实现集成。本节介绍如何使用Vert.x的HTTP客户端API与第三方Web服务进行集成。场景:备份到GitHub Gist在GitHub的要点服务是广受欢迎的共享代码段到世界各地。其他服务可以使用它,例如中等发布平台,其中指向Gist的链接允许将代码片段嵌入到发布中。GitHub...

zyydecsdn的博客 1163

vertx 学习之Future

一、并发组合执行。CompositeFuture.all 接受多个future参数(最多6个);当所有的future都成功了,就返回成功的future,否则只要有一个失败就会返回失败(failed)的future: Future&lt;JsonObject&gt; fut1 = Future.future(); Future&lt;JsonObject&gt; fut2 = Fu...

qq_34227896的博客 8452

Vertx-future.complete()

问题由来: 今天项目上这样写 FutureVoid> replyFuture = Future.future(); replyMsg(baseAppMsg).setHandler(as -> { if (as.succeeded()) { LOGGER.info("回复成功"); replyFuture.complete(); Htt

Andaren的博客 2713

Netty事件流程分析补充

pipeline责任链流程分析 责任链创建流程 入口程序 // 责任链的创建是在Channel的初始化的时候进行的 // AbstractChannel.java protected AbstractChannel(Channel parent) { // 如果当前为服务端的channel,则parent=null this.parent = parent; // 创建channe...

疾风先生的博客 950

自顶向下深入分析Netty(五)--Future

Netty架构模式 再次回顾这幅图,在上一章中,我们分析了Reactor的完整实现。由于Java NIO事件驱动的模型,要求Netty的事件处理采用异步的方式,异步处理则需要表示异步操作的结果。Future正是用来表示异步操作结果的对象,Future的类签名为: public interface FutureV>; 其中的泛型参数V即表示异步结果的类型。 5.1 总

Fashion-liu的博客 2585

vertx的Future模式的实现FutureImpl分析

文章目录问题解决我们看vert.x里面的Future的具体实现先看isComplete方法,再看setHandler方法再看complete方法如果. 问题 在使用异步编程的时候,Future模式实现需要注意几个问题: 当提前已经Complete,但是还没有设置Handler,这时候需要在设置Handler的时候执行Handler方法 当提前已经设置了Handler,在执行Complete方法的...

你就像甜甜的益达 1324

Vert.x 响应式 Web 框架介绍使用

一、Vert.x Vert.x 是JVM上构建 响应式 应用的工具。 响应式应用既可以随着工作负载的增长而 扩展 ,又可以在出现故障时 弹性回复 。 响应式应用是 即时响应 的,因为它能有效利用系统资源并保护自身免受错误影响,从而使延迟可控。Vert.x 背靠庞大的响应式模块生态系统,具有编写现代服务所需的一切:全面的Web技术栈,响应式数据库驱动程序、消息队列、事件流、集群支持、指标监控、分布式跟踪等等。 Vert.x最大的特点就在于异步(底层基于Netty),通过事件循环(EventLoop)来调起存储

小毕超博客 6575

vertx web开发(一)

vertx web开发 最近在开发中,由于spring 的大而全,反而不实用于一下小项目,因为spring boot在空载的情况,至少其内存占用超过150M.而对于一些简单的项目反到不适用。而反观vertx,这是一个全异步编程的框架,具体可查,其异步编程从某种角度来说可以使并发量极大的提高。特别使vertx 配合kotlin,可以让你拥有同步的思想来进行异步开发。 一、创建HTTP server 引进相关的包,gradle项目添加相关依赖 // vert core impleme

myenjoy_1的博客 676

vertx web开发(二)

前言 上文介绍了vertx的基本用法,并且结合kotlin的特性,为future写了几个比较有用的扩展函数,本文将主要为vertx web开发的路由进行探索。 Route初使用 在官方文档中,引进包 ‘io.vertx:vertx-web:3.4.2’,即可获取路由能力,从官方的例子如下代码: router.route("/some/path/").handler(routingContext -> { HttpServerResponse response = routing..

myenjoy_1的博客 491

Vert.x-Web与SpringBoot整合

Vert.x的各种优点本文就不再赘述了,感兴趣的朋友可以看一下博主的另一篇博文《Spring Boot同步架构与Vert.x异步架构高并发性能对比》。本文主要介绍博主整理开发的Vertx与SpringBoot整合的脚手架项目。项目旨在便于现有spring项目与Vert.x整合,既能体验Vert.x的高效又兼顾spring的泛用性,降低Vert.x的学习和使用成本,可以做到spring到Vert.x...

Ian的博客 1万+
上一篇: Vert.x Java开发指南——第五章 测试Vert.x代码
下一篇: Vert.x Java开发指南——第七章 公开Web API
边城白衣
博客等级 码龄14年 106粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值