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。

使用SSE流式输出(Javaweb前后端实战) SSE(Server-Sent Events)是一种在Web应用中实现单向实时通信的技术。通过SSE,服务器可以主动向客户端发送更新,而无需客户端不断发起请求。这对于需要实时更新的应用场景(如聊天应用、实时数据监控等)非常有用。(服务端单向传输客户端,长连接) 阅读详情

相关推荐

疑难问题(二)——PyTorch 2.3.0 ‘import torch‘ 错误排查:深入解析‘shm.dll‘加载失败与系统路径修复

本文深入解析了在Windows系统上安装PyTorch 2.3.0后,执行'import torch'时遇到的'shm.dll'加载失败错误(OSError)。该问题通常源于系统DLL搜索路径缺失,导致无法找到关键的共享内存通信组件或其依赖项。文章提供了核心解决方案:通过手动修改PyTorch的`__init__.py`文件,将用户基目录下的Library\bin路径添加到DLL搜索列表中,从而从根本上修复此导入错误,并给出了详细的修改步骤和验证方法。

weixin_29056865的博客 305

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

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

边城白衣的博客 3388

LibreNMS实战:5分钟搞定Docker部署与中文配置(附常见问题排查)

本文详细介绍了如何使用Docker在5分钟内快速部署LibreNMS,并完成中文界面优化。从环境准备到容器启动,再到中文语言包安装和系统配置调整,提供了完整的实战指南。同时,文章还包含常见问题排查和性能调优建议,帮助用户高效搭建网络监控系统。

e1f2g的博客 1281

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

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

zyydecsdn的博客 2305

反激开关电源设计全解析:从CCM/DCM原理到PCB布局实战

开关电源作为现代电子设备的能量转换核心,其核心原理是通过高频开关动作实现高效的电能变换。反激拓扑因其结构简单、成本低廉且易于实现电气隔离,成为小功率离线式电源的主流选择。其技术价值在于通过变压器耦合实现能量存储与传递,解决了安全隔离与多路输出等关键需求,广泛应用于充电器、适配器及家电供电等场景。本文聚焦反激电路,深入剖析其CCM与DCM两种工作模式的原理差异及选型考量,并结合伏秒平衡定律与RCD钳位等热词,详解从变压器计算到MOSFET选型的完整工程设计流程。

weixin_31951365的博客 343

行政数据分析大屏实战:用Tableau从Excel到看板的完整搭建流程(含数据连接与字段计算避坑)

本文详细介绍了如何利用Tableau从Excel数据源搭建行政数据分析大屏的完整流程,涵盖数据准备、连接技巧、计算字段优化、看板设计及动态交互部署。通过五阶工作流,帮助用户高效处理多源异构数据,实现业务洞察与可视化呈现,提升行政数据分析效率。

weixin_29696711的博客 338

vert.x框架学习笔记

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

zwj1030711290的优快云 3624

别再乱选离散化方法了!从零到一用Matlab对比差分、双线性Tustin和预矫正的实战效果

本文深入探讨了Matlab中四种主流离散化方法(差分、双线性Tustin和预矫正)的实战效果对比,帮助工程师在数字控制系统设计中做出明智选择。通过详细的理论分析和Matlab代码示例,展示了不同方法在稳定性、频率响应和计算复杂度上的差异,并提供了针对不同场景的工程选用指南。

weixin_28737603的博客 141

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

置顶必读(1) | 滚雪球学Oracle教程导航帖,带你弯道超车(持续更新中)

什么是数据库管理系统(DBMS),Oracle在行业中的领先地位Oracle数据库的市场竞争与主要应用场景Oracle数据库的核心功能模块与未来技术发展趋势约束的高级应用:主键、唯一性、外键设计与管理表分区、视图、同义词与序列的最佳实践PL/SQL编程的设计哲学,如何高效使用Oracle SQL DeveloperPL/SQL代码调试与优化技巧RAC集群中的高可用性设计,负载均衡与并行查询的配置集群中的缓存一致性管理。

**My Coding Family** 1万+

2024年下半年网络规划设计师论文真题

3、深入论述自身参与的工业网络是如何实施的,为实现制造业的智能化,如何实现数据的跨系统互通,促进各种工业数据的充分流动和无缝集成以及数据安全。3、结合自身参与的网络建设,详细叙述针对该网络“去NAT”的规划和设计方案。4、在实施过程中遇到的问题以及如何处理,项目实施后的效果和评价。2、大型园区网络“去NAT”改造和业务融合的整体架构。1、“网络去NAT”对推进ipv6演进和应用的意义。4、改造过程中遇到的问题及解决方案。2、简要叙述自身参与的制造网络建设。1、网络规划在智能制造中的意义。

鹿鸣天涯 2365

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

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

白石的专栏 2309

第42章:AI代码生成的质量标准——何时用AI、何时自己写

> - AI代码生成的质量分级标准:可用、稳定、安全、优雅 > - 一个决策矩阵:什么场景适合用AI,什么场景必须人工编写 > - 如何评估AI生成的代码质量(复杂度、可读性、安全性) > - 实战对比:同一需求下AI生成代码 vs 人工编写代码 > - 团队落地:将质量标准集成到Code Review和CI流程 > - 我如何将团队AI代码接受率从70%提升到90%

sfishfly的博客 161

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

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

happyfly的博客 2万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

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

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

lgleje的博客 1709

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

vertx的Future设计

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

weixin_30325487的博客 1263

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

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 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、付费专栏及课程。

余额充值