迁移

从 Vert.x 4 迁移到 5

本指南介绍了 Eclipse Vert.x 5 版本中的更新。您可以使用此信息将 Vert.x 4.x 应用程序升级到 Vert.x 5。它提供了有关此版本中新增、已弃用和不受支持功能的信息。

根据您的应用程序中使用的模块,您可以阅读相关章节以了解 Vert.x 5 中的更改。

关于 Vert.x

Vert.x 是一个工具包,用于创建运行在 Java 虚拟机(JVM)上的响应式、非阻塞和异步应用程序。它包含多个组件,可帮助您创建响应式应用程序。它被设计为云原生。

由于 Vert.x 支持异步应用程序,因此可用于创建具有大量消息、大型事件处理、HTTP 交互等功能的应用程序。

Vert.x 5 有哪些变化

本节解释了 Vert.x 5 和 4.x 版本之间的根本区别。

处理弃用和移除

Vert.x 5 中已弃用或移除了某些特性和功能。在将应用程序迁移到 Vert.x 5 之前,请检查弃用和移除情况。

  • 在 Vert.x 4.x 版本中,某些 API 已被弃用,并在该版本中提供了新的等效 API。

  • 已弃用的 API 已在 Vert.x 5 中移除。

如果您的应用程序使用已弃用的 API,您应该更新您的应用程序以使用新的 API。这有助于将应用程序迁移到产品的最新版本。

当使用已弃用的 API 时,Java 编译器会生成警告。在将应用程序迁移到 Vert.x 5 时,您可以使用编译器检查已弃用的方法。

组件的逐渐淘汰和移除

一些组件在 5.x 系列中逐渐淘汰,这意味着它们在 5.x 系列的生命周期内仍受支持,但我们不再鼓励使用它们,因为我们提供了替代方案。这些组件计划在下一个主要版本(Vert.x 6)中移除。

以下是 5.x 版本中逐渐淘汰的组件列表

组件 替代方案

gRPC Netty

Vert.x gRPC 客户端和服务器

JDBC API

JDBC 的 SQL 客户端 API 实现

服务发现

Vert.x 服务解析器

RxJava 2

Mutiny 或 RxJava 3

OpenTracing

OpenTelemetry

Vert.x Unit

Vert.x JUnit 5

以下是 Vert.x 5 中移除的组件列表,这些组件在 4.x 系列中已逐渐淘汰。

组件 替代方案

Vert.x Sync

Vert.x 虚拟线程

服务工厂

Maven 服务工厂

HTTP 服务工厂

Vert.x Web OpenAPI

Vert.x Web OpenAPI 路由器

拥抱未来模型

Vert.x 4 将 3.x 的回调异步模型扩展为未来/回调混合模型,以方便从 Vert.x 3 迁移。

每个回调方法都有一个匹配的未来方法

public interface HttpClient {

   // Future version
   Future<HttpClientRequest> request(RequestOptions request);

   // Callback version
   void request(RequestOptions request, Handler<AsyncResult<HttpClientRequest>> callback);
   ...
}

Vert.x 5 只保留未来模型,因此回调模型已消失,取而代之的是

public interface HttpClient {

   // Future version
   Future<HttpClientRequest> request(RequestOptions request);
   ...
}

Vert.x 4.x 中的回调方法不是已弃用的方法,但在 Vert.x 5 发布后,回调方法将弃用,以方便迁移到 Vert.x 5。

Vert.x 构建器

Vert.x 5 引入了构建器模式的使用,该模式方便了组件与对象实例的配置。

直到 Vert.x 5,这种定制通常通过选项来支持。

在 Vert.x 4.x 中定制 Vertx 实例
Future<Vertx> future = Vertx.clusteredVertx(options.setClusterManager(clusterManager));

构建器模式提供了一种清晰简单的替代方案,用于分离配置定制

在 Vert.x 5 中定制 Vertx 实例
Future<Vertx> f = Vertx
  .builder()
  .with(options)
  .withClusterManager(clusterManager)
  .buildClustered();

在 Vert.x 5 中,此模式已尽可能地被采纳,并将按组件详细说明。

Vert.x 命令行工具移除

vertx 命令行工具已在 Vert.x 5 中移除。

我们希望专注于典型的 Vert.x 应用程序用例:编译并可选择打包为可执行的 uber-jar。

您可以使用 Maven 和 Vert.x Maven 插件来完成此操作。该插件可以在您的仓库中创建新的 Maven 项目或更新现有项目。

除了将应用程序打包为可执行的 uber-jar 之外,它还可以在开发模式下启动您的应用程序(当检测到文件更改时重新部署主 verticle)。

如果您是 Gradle 用户,Vert.x Gradle 插件提供了类似的功能。

CLI 框架弃用

CLI 框架在 Vert.x 5 中已被弃用。这包括基于它的 io.vertx.core.Launcher 类。

如果您的应用程序是命令行工具或需要一个,请查看 Picocli 等替代方案。事实上,在许多方面,Picocli 比 Vert.x CLI 框架更灵活、更强大。

Vert.x 旧版 CLI

如果在评估替代方案时,您需要保留 CLI 框架功能,可以通过将此依赖项添加到您的项目(Maven)中来实现:

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-launcher-legacy-cli</artifactId>
  <version>5.0.0</version>
</dependency>

这个新项目包含旧版 CLI 框架,包括 io.vertx.core.Launcher 类。

请注意,不能保证在 Vert.x 5 的整个生命周期内都能保持向后兼容性。

Vert.x 应用程序启动器

在 Vert.x 5 中,一个新的模块,即 Vert.x 应用程序启动器,取代了 Vert.x 4.x 的 io.vertx.core.Launcher 类。

首先,您必须将其添加到项目的依赖项中(Maven)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-launcher-application</artifactId>
  <version>5.0.0</version>
</dependency>

要启动应用程序,请使用 io.vertx.launcher.application.VertxApplication 作为主类。

# Assuming the command is executed on a Unix-like system which has the classpath configured in the CLASSPATH environment variable.
java -cp $CLASSPATH io.vertx.launcher.application.VertxApplication my.app.MainVerticle

如果您的应用程序打包为可执行 JAR,并且在 META-INF/MANIFEST.MF 文件中将 Main-Class 属性设置为 io.vertx.launcher.application.VertxApplication,则命令可以简化。

java -jar myapp.jar my.app.MainVerticle

Vert.x 5 应用程序启动器不支持文件更改时 verticle 的实时重新部署。如果您在开发阶段需要此功能,并且您的项目是使用 Maven 构建的,请查看 Vert.x Maven 插件

Vert.x 核心

Vert.x 实例定制

Vertx 实例可以通过一些可变部分进行定制

  • 集群管理器

  • 指标工厂

  • 跟踪工厂

在 Vert.x 5 中,通过 VertxBuilder 实现定制。

使用集群管理器进行定制
// 4.x
Future<Vertx> f = Vertx.clusteredVertx(
  new VertxOptions().setClusterManager(clusterManager)
);

// 5.0
Future<Vertx> f = Vertx
  .builder()
  .withClusterManager(clusterManager)
  .buildClustered();

同样,指标和跟踪工厂的配置方式也类似

使用跟踪/指标工厂进行定制
// 4.x
Vertx vertx = Vertx.vertx(
  new VertxOptions()
    .setMetricsOptions(new MetricsOptions().setEnabled(true).setFactory(factory))
    .setTracingOptions(new TracingOptions().setFactory(factory))
);

// 5.0
Vertx vertx = Vertx
   .builder()
  .withMetrics(factory)
  .withTracer(factory)
  .build();

Vert.x 的跟踪实现已相应更新,以支持为此目的使用跟踪器实现进行定制

使用 OpenTelemetry 实例定制实例
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
    .setTracingOptions(
      new OpenTelemetryOptions(openTelemetry)
    )
  );

// 5.0
Vertx vertx = Vertx.builder()
 .withTracer(new OpenTelemetryTracingFactory(openTelemetry))
 .build();

Vert.x 的指标实现已相应更新,以支持为此目的使用指标实现进行定制

使用 Dropwizard 指标注册表定制实例
// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
 .setMetricsOptions(new DropwizardMetricsOptions()
   .setMetricsRegistry(myRegistry)
   .setEnabled(true)));

// 5.0
Vertx vertx = Vertx.builder()
  .with(new VertxOptions()
    .setMetricsOptions(new DropwizardMetricsOptions()
    .setEnabled(true)))
  .withMetrics(new DropwizardMetricsFactory(myRegistry))
  .build();

HTTP/2 连接关闭处理程序

HTTP/2 连接关闭处理程序在连接开始关闭时通知处理程序,以前是所有连接流关闭后才通知处理程序。旧的行为可以通过连接关闭处理程序获得。

这使得可以感知连接关闭并采取适当措施停止正在处理中的流。它也与其它关闭处理程序的行为保持一致。

移除不带时间单位的 HTTP 连接关闭变体

HttpConnection#shutdown(long) 变体已被移除,取而代之的是 HttpConnection#shutdown(long, TimeUnit)

// 4.x
connection.shutdown(5 * 1000); // 5 seconds

// 5.0
connection.shutdown(5, TimeUnit.SECONDS); // 5 seconds

移除带有字符串 authority 的 HTTP 服务器响应推送方法

带有字符串 authorityHttpServerResponse#push 方法已被移除,取而代之的是使用 HostAndPort 类型作为 authority 的相同方法。

// 4.x
response.push(httpMethod, authorityAsString path);

// 5.0
response.push(httpMethod, HostAndPort.parse(authorityAsString) path);

已弃用的 HttpServerRequest#cookieMap 方法已被移除,应使用 HttpServerRequest#cookies 方法。

// 4.x
Map<String, Cookie> cookieMap = request.cookieMap();

// 5.0
Set<Cookie> cookies = request.cookies();

HTTP/2 流使用统一字节分发器

默认的流字节分发器使用流优先级来确定每个流要发送的字节量,此更改允许使用不使用流优先级且性能更好的策略,因为它消耗更少的 CPU。

默认实现现在是 UniformStreamByteDistributor 而不是 WeightedFairQueueByteDistributor

将 HttpClientRequest setTimeout 重命名为 setIdleTimeout

请求超时实际上是空闲超时,为了避免混淆,已将其重命名。

// 4.x
request.setTimeout(timeout);

// 5.0
request.setIdleTimeout(timeout);

移除 HttpClient WebSocket 方法

HttpClient WebSocket 方法已移至新的 WebSocketClient API。

// 4.x
HttpClient httpClient = vertx.createHttpClient();
Future<WebSocket> f = httpClient.webSocket(connectOptions);

// 5.0
WebSocketClient wsClient = vertx.createWebSocketClient();
Future<WebSocket> f = wsClient.connect(connectOptions);

HTTP 客户端定制

HttpClient 定制方法已移至新的 HttpClientBuilder

  • redirectHandler

  • connectionHandler

// 4.x
HttpClient client = vertx.createHttpClient();
client.connectionHandler(conn -> ...);
client.redirectHandler(request -> ...);

// 5.0
HttpClient client = vertx.httpClientBuilder()
  .withConnectHandler(conn -> ...)
  .withRedirectHandler(request -> ...)
  .build();

HttpClient API 清理

在 Vert.x 4.x 中,HttpClient API 暴露了两个不同的 API

  • HTTP 交互,如 request 方法。

  • HTTP 客户端操作,如 updateSSLOptions

自 Vert.x 5 起,HttpClient 只保留 HTTP 交互,一个新的 HttpClientAgent API 扩展了 HttpClient 并暴露了这些方法

// 4.x
HttpClient client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);

// 5.0
HttpClientAgent client = vertx.createHttpClient();
client.updateSSLOptions(sslOptions);

HttpClient 连接池配置

在 Vert.x 4.x 中,HttpClientOptions 配置 HTTP/1.x 和 HTTP/2 连接池。

自 Vert.x 5 起,此配置通过 PoolOptions 完成。

// 4.x
HttpClient client = vertx.createHttpClient(new HttpClientOptions()
  .setMaxPoolSize(http1MaxPoolSize)
  .setHttp2MaxPoolSize(http2MaxPoolSize)
);

// 5.0
HttpClient client = vertx.createHttpClient(new PoolOptions()
  .setHttp1MaxSize(http1MaxPoolSize)
  .setHttp2MaxSize(http2MaxPoolSize)
);

移除 HttpServerResponse close 方法

HttpServerResponse 的 close 方法会关闭 HTTP 连接,这可能会引起误解,因为有更好的 API 可以与当前请求/连接生命周期进行交互,即 HttpServerResponse#resetHttpConnection#close

当必须关闭实际 HTTP 连接时

// 4.x
response.close();

// 5.0
request.connection().close();

当必须处理当前请求/响应时

// 4.x
response.close();

// 5.0
response.reset();

HTTP 流异步方法现在返回 Future 而不是流式接口

为了指示完成结果,一些方法的流式返回类型已更改为 Future 类型

  • writeCustomFrame

  • writeContinue

  • reset

// 4.x
response.writeCustomFrame(12, 134, expectedRecv).end();

// 5.0
response.writeCustomFrame(12, 134, expectedRecv);
response.end();

新的 authority 属性取代 host/port

HttpClientRequestHttpServerRequest 使用客户端请求的 host/port 组合和服务器的单个 host 头来暴露请求的 authority。此外,此术语与实际的服务器 host 和 port 也容易混淆。

这些被新的 authority 属性取代

客户端请求
// 4.x
request.setHost(host).setPort(port);

// 5.0
request.authority(HostAndPort.create(host, port));
服务器请求
// 4.x
String host = request.host(); // host:port string

// 5.0
HostAndPort authority = request.authority();

HttpServer 请求和 WebSocket 流移除

HttpServer#requestStream()HttpServer#timeoutStream() 已被移除。这些流是为类似 Rx 的语言设计的,但实际上并未提供任何好处。

// 4.x
server.requestStream().handler(request -> ...);

// 5.0
server.requestHandler(request -> ...).listen();

移除服务器 WebSocket 握手方法

服务器 WebSocket API 可以隐式(例如,发送消息)或显式(接受或任何 WebSocket 交互)控制握手。这导致了比此类 API 应有的更复杂的实现。

这两个步骤现在是分开的

  • WebSocket 握手处理程序根据应用程序特定的标准接受或拒绝服务器 WebSocket 连接

  • WebSocket 处理程序配置 WebSocket 并照常执行交互

接受握手
// 4.x
server.webSocketHandler(ws -> {
  ws.handler(msg -> ...);
  ws.accept();
  ws.write();
};

// 5.0
server.webSocketHandshakeHandler(handshake -> {
  handshake.accept();
});
server.webSocketHandler(ws -> {
  ws.handler(msg -> ...);
  ws.write();
};
拒绝握手
// 4.x
server.webSocketHandler(ws -> {
  ws.reject();
};

// 5.0
server.webSocketHandshakeHandler(handshake -> {
  handshake.reject();
});

Future

CompositeFuture 原始 Future 类型移除

CompositeFuture 方法声明了原始的 Future 类型,例如 all(Future,Future)all(List<Future>>),这种声明在使用 List<Future<Something>> 时强制用户进行类型转换。这些方法已使用通配符类型完全泛化。

List<Future<User>> users = ...

// 4.x
CompositeFuture cf = CompositeFuture.all((List<Future>)users);

// 5.0
CompositeFuture cf = Future.all(users);

移除以函数作为参数的 Future eventually 方法

Future#eventually 方法以 Function<Void, Future<T>> 作为参数,这是为不支持 Supplier 的代码生成而开发的。自 Vert.x 4.x 以来,Future 对象不再进行代码生成,因此我们可以使用更合适的 Supplier

// 4.x
future.eventually(v -> someFuture());

// 5.0
future.eventually(() -> someFuture());

日志

Vert.x 4 中 Vert.x 日志 API 的使用已减少到仅供 Vert.x 组件内部使用,换句话说,该 API 已成为 Vert.x 的内部 API。

io.vertx.core.logging.Loggerio.vertx.core.logging.LoggerFactory 已被弃用,以劝阻使用此 API。相反,应使用 Log4j 2SLF4J 等日志 API。

当然,Vert.x 日志后端的配置仍然像往常一样完全支持,例如 vertx.logger-delegate-factory-class-name 系统属性。

系统属性

Vert.x 5 中移除了一些系统属性。

名称 注释

vertx.json.base64

Vert.x 3.x Json 支持 RFC-7493,但 JSON 编码器/解码器格式不正确。需要与 Vert.x 3.x 应用程序互操作的用户应将系统属性 vertx.json.base64 设置为 legacy

vertx.cluster.managerClass

未使用,既未文档化也未测试。

vertx.javaCompilerOptions

未使用,既未文档化也未测试。

vertx.flashPolicyHandler

Vert.x HTTP/1.1 服务器包含一个隐藏选项,用于检测 Adobe Flash 客户端并返回策略文件响应。此选项仅由源文件中引用的系统属性 vertx.flashPolicyHandler(私有字段)激活,且未经过测试。

vertx.cwd

此系统属性未被文档化,并且仅在 vertx-examples 仓库中使用。

vertx.disableTCCL

应使用 VertxOptions#setDisableTCCL(boolean)

工作 Verticle

移除部署 worker 属性

自引入新的 ThreadingModel 以来,DeploymentOptions#setWorkerDeploymentOptions#getWorker 方法已被移除。

// 4.x
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setWorker(true, ...)

// 5.0
Future<String> f = vertx.deployVerticle(new DeploymentOptions().setThreadingModel(ThreadingModel.WORKER, ...)

工作线程事件循环分配

自 Vert.x 5 起,工作线程部署为所有工作 verticle 使用单个事件循环,而不是每个工作实例一个事件循环。

以前,这是遵循事件循环部署的,为可伸缩性目的,每个 verticle 实例使用一个事件循环。

事件总线变化

消息消费者动态最大缓冲消息移除

事件总线消息消费者具有动态最大缓冲消息上限。相反,这应该在创建消费者时进行配置。

// 4.x
eventBus.consumer(ADDRESS, msg -> ...).setMaxBufferedMessages(2000);

// 5.0
eventBus.consumer(new MessageConsumerOptions()
     .setAddress(ADDRESS)
     .setMaxBufferedMessages(2000)
   , msg -> ...);

文件系统

文件系统删除方法中的 recursive 布尔值移除

FileSystem#deleteRecursive(…​) 方法声明了一个 recursive 布尔值,它与调用 FileSystem#delete 几乎相同,因此用户应直接调用 deletedeleteRecursive

// 4.x
stream.deleteRecusrive(path, false);

// 5.0
stream.delete(path);

同样,

// 4.x
stream.deleteRecursive(path, true);

// 5.0
stream.deleteRecursive(path);

杂项

NetServer 连接流移除

NetServer#connectStream() 已被移除。此流是为类似 Rx 的语言设计的,但实际上并未以 API 为代价提供任何好处。

// 4.x
server.connectStream().handler(socket -> ...);

// 5.0
server.connectHandler(socket -> ...).listen();

NoStackTraceThrowable 更改

`Future#fail(String msg)` fail the future with a `NoStackTraceThrowable` wrapping the error message.

当虚拟线程等待 Future 的结果时,如果发生故障,会重新抛出 NoStackTraceThrowable,这会强制虚拟线程捕获 Throwable 实例。

自 Vert.x 5 起,NoStackTraceThrowable 的超类是 VertxException

// 4.x
try {
  future.await();
} catch(Throwable t) {
  ...
}

// 5.0
try {
  future.await();
} catch(Exception t) {
  ...
}

这影响了 Vert.x 虚拟线程和 Kotlin 协程的使用。

TimeoutStream 移除

TimeoutStream 已被移除。此流是为类似 Rx 的语言设计的,但实际上并没有以牺牲 API 为代价提供任何好处。相反,应使用框架调度器和 Vert.x 上下文。

// 4.x
vertx.periodicStream(1L).handler(timerID -> ...);

// 5.0
server.setPeriodic(1L, timerID -> ...);

对于 RxJava 类似集成

// 4.x
Observable<Long> timer = vertx.periodicStream(1000).toObservable();

// 5.0
Scheduler scheduler = RxHelper.scheduler(vertx);
Observable<Long> timer = Observable.interval(100, 100, TimeUnit.MILLISECONDS, scheduler);

上下文本地存储更改

旧版上下文本地存储 API 已从公共 API 中移除。

以下方法已移至 io.vertx.core.internal.ContextInternal 接口,并可能随时在 Vert.x 5 中移除。

上下文本地存储与以前的 API 非常相似

// 4.x
context.putLocal("custom", new CustomLocal());

// 5.0
context.putLocal(CustomLocal.KEY, new CustomLocal());

必须进行适当的自定义本地声明

public class CustomLocal implements VertxServiceProvider {
  public static final ContextLocal<CustomLocal> KEY = ContextLocal.registerLocal(CustomLocal.class);
  /*
    Holds some state
   */
}

此类提供者必须在 META/INF/services/io.vertx.core.spi.VertxServiceProvider 中声明为 Java 服务提供者,并可选择在 module-info.java 中声明。

keyCertOptions 密钥管理器映射器移除

KeyCertOptions#keyManagerMapper() 方法已在 Vert.x 5 中移除,实现者必须转而实现 keyManagerFactoryMapper 方法,该方法提供了将 KeyManagerFactory 缓存到控制密钥管理器生命周期的实现者的机会。

移除带 Promise 处理程序的阻塞执行方法

用于执行阻塞操作的 API 使用带处理程序完成或失败 Promise 的模式,这可以替换为返回相同值或抛出异常的 java.util.concurrent.Callable

// 4.x
Future<String> fut = vertx.executeBlocking(promise -> promise.complete("result"));

// 5.0
Future<String> fut = vertx.executeBlocking(() -> "result");

processArgs 方法已弃用

io.vertx.core.Context#processArgsio.vertx.core.AbstractVerticle#processArgs 已弃用。

自版本 5 起,Vert.x 不再与 CLI 紧密耦合。

Netty 类型使用移除

Vert.x API 在其公共 API 中暴露了 Netty API,允许与 Netty API 进行交互。由于 Netty 正在向 Netty 5 发展,我们应该在 Vert.x 5 中从 Vert.x 公共 API 中移除 Netty API,以便有机会更改 Vert.x 使用的底层 Netty 版本,而不必担心 Netty 版本。

此类 API 在 Vert.x 5 中仍然存在,但已移至内部 API,不具有契约性,因此使用此 API 的有经验的用户可以继续使用它,前提是 Vert.x 5 版本使用 Netty 4。

// 4.x
ByteBuf bb = buff.getByteBuf();
Buffer buf = Buffer.buffer(bb);
EventLoopGroup group = vertx.nettyEventLoopGroup();

// 5.0
ByteBuf bb = ((BufferInternal)buff).getByteBuf();
buf = BufferInternal.buffer(bb);
group = ((VertxInternal)vertx).nettyEventLoopGroup();

Vert.x Auth

AuthProvider 剪枝

io.vertx.ext.auth.AuthProvider 已在 Vert.x 4.0 中弃用,取而代之的是 io.vertx.ext.auth.authentication.AuthenticationProvider

// 4.x
AuthProvider authProvider = ...

// 5.0
AuthenticationProvider authProvider = ...

Vert.x for Kotlin

移除 await 扩展方法生成

Vert.x 4.x for Kotlin 生成挂起扩展方法,以方便调用 Vert.x 异步方法。

suspend fun HttpServer.listenAwait(port: Int, host: String): HttpServer {
   return awaitResult {
     this.listen(port, host, it)
  }
}

此类方法已弃用,因为可以使用 Vert.x Future 实例实现相同效果,并在 Vert.x 5 中移除。

// 4.x
server.listenAwait(port, host)

// 5.0
server.listen(host, port).coAwait()

Vert.x gRPC

移除 GrpcReadStream#collecting,取而代之的是 ReadStream#collect

// 4.x
stream.collecting(collector);

// 5.0
stream.collect(collector);

移除声明方法描述符的方法

声明 MethodDescriptorGrpcClient/GrpcServer 方法已被移除。

相反,这些方法现在在扩展 GrpcClient/GrpcServer 接口的 GrpcIoClient/GrpcIoServer 接口中可用。

// 4.x
GrpcServer server = GrpcServer.create(vertx);

// 5.0
GrpcIoServer server = GrpcIoServer.create(vertx);
server.callHandler(methodDescriptor, request -> ...);

Vert.x Web

RoutingContext 用户 API

用户相关操作已移至可从 RoutingContext 访问的单个上下文 API 下

注销

// 4.x
routingContext.clearUser();

// 5.0
UserContext userContext = routingContext.userContext();
userContext.logout();

设置用户

RoutingContext#setUser 方法已被移除,此操作应由身份验证处理程序执行。

静态处理程序配置

StaticHandler 方法 setAllowRootFileSystemAccesssetWebRoot 在 Vert.x 4.x 中弃用后已移除。

相反,处理程序必须在创建时配置

// 4.x
StaticHandler handler = StaticHandler.create().setAllowRootFileSystemAccess(true).setWebRoot(root);

// 5.0
StaticHandler handler = StaticHandler.create(FileSystemAccess.ROOT, root);

解包模板引擎

模板引擎获取底层引擎实例的方法在弃用后已移除

  • HandlebarsTemplateEngine#getHandlebars

  • ThymeleafTemplateEngine#getThymeleafTemplateEngine

应使用 TemplateEngine#unwrap

// 4.x
Handlebars handlebarsUnwrapped = handlebarsTemplateEngine.getHandlebars();
TemplateEngine thymeleafUnwrapped = thymeleafTemplateEngine.getThymeleafTemplateEngine();

// 5.0
handlebarsUnwrapped = handlebarsTemplateEngine.unwrap();
thymeleafUnwrapped = thymeleafTemplateEngine.unwrap();

CORS 正则表达式来源

基于正则表达式来源的方法的命名已更改,以与框架的其余部分保持一致

  • CorsHandler#addRelativeOrigin

  • CorsHandler#addRelativeOrigins

应使用 addOriginWithRegexaddOriginsWithRegex

// 4.x
CorsHandler.addRelativeOrigin(".*");
CorsHandler.addRelativeOrigins(List.of(".*", "https?://.*"));

// 5.0
CorsHandler.addOriginWithRegex(".*");
CorsHandler.addOriginsWithRegex(List.of(".*", "https?://.*"));

Vert.x Web 客户端

响应预期替换

Vert.x Core 引入了一个新的 API,用于实现受 Web 客户端响应预期功能启发的预期检查。

Vert.x HTTP 客户端附带与 Web 客户端响应预期相同的预定义预期集,更重要的是 HTTP 客户端响应预期可由 Web 客户端重复使用。

HTTP 响应预期利用了新的 Future#expecting 操作与 HttpResponseExpectation 实现的组合。

// 4.x
client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .expect(ResponsePredicate.SC_SUCCESS)
  .send()
  .onSuccess(res -> {
    // ....
  });

// 5.0
client
  .get(8080, "myserver.mycompany.com", "/some-uri")
  .send()
  .expecting(HttpResponseExpectation.SC_SUCCESS)
  .onSuccess(res -> {
    // ....
  });

Vert.x Web GraphQL

升级到 GraphQL-Java 23

Vert.x Web GraphQL 已从 GraphQL-Java 20 升级到 GraphQL-Java 23。

GraphQL-Java 22 和 23 是重大变更版本

Vert.x Web 验证

替换已弃用的 SchemaParser

Vert.x Web Validation 曾基于已弃用的 JSON Schema API,该 API 在 Vert.x 5 中不再可用。

// 4.x
ValidationHandlerBuilder.create(schemaParser)

// 5.0
SchemaRepository schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7));
ValidationHandlerBuilder.create(schemaRepo);
为了提高安全性,新的 SchemaRepository 不会自动加载外部引用。如果您的模式包含外部引用,您必须预先提供并解引用它们。

Vert.x SQL 客户端

客户端构建器

Pool 子类型并没有真正的用处,因为它们不携带任何额外的方法,主要用于静态构建池。

此外,由于重载,这些静态方法不够灵活且数量众多。

我们正在用新的客户端构建器 API 替换这些方法。

// 4.x
PgPool client = PgPool.pool(vertx, connectOptions, poolOptions);

//5.0
Pool client = PgBuilder.pool()
  .with(poolOptions)
  .connectingTo(connectOptions)
  .using(vertx)
  .build();

连接选项

SqlConnectOptions 类不再继承 NetClientOptions 类。

SqlConnectOptions TLS 配置仍在此类上进行。

// 4.x
// 5.0
PgConnectOptions options = new PgConnectOptions()
  .setPort(port)
  .setHost(host)
  .setDatabase(database)
  .setUser(user)
  .setPassword(password)
  .setSslOptions(new ClientSSLOptions()
    .setTrustOptions(new PemTrustOptions().addCertPath(pathToCert))
  );

通过 ClientBuilder,仍然可以在构建客户端时传递 NetClientOptions

// 5.0
Pool pool = PgBuilder.pool()
      .connectingTo(connectOptions)
      .with(tcpOptions)
      .build();

池连接处理程序

Pool#connectHandler 方法已移至新的 ClientBuilder,处理程序在构建时设置一次,而不是作为池实现的 mutable 字段。

// 4.x
pool.connectHandler(connectHandler);

// 5.0
builder.connectHandler(connectHandler);

池连接提供者

Pool#connectionProvider 方法被 Supplier<Future<SqlConnectOptions>> 构建器方法取代。

// 4.x
pool.connectionProvider(ctx -> futureOfSqlConnection(ctx));

// 5.0
builder.connectingTo(() -> futureOfSqlConnectOptions());

Vert.x Mongo 客户端

升级到 MongoDB Java Driver 5

MongoDB Java Driver 5.x 是一个重大变更版本

IndexOptions 中,bucketSize 已被移除。

此外,StreamFactoryFactory 已被 TransportSettings 取代,并且 Netty 是唯一可用的传输方式。

Vert.x Redis 客户端

移除请求空参数

Redis 不接受请求中的 null 值。因此,Request#nullArg() 方法将 null 编码为 4 个字符的 "null" 字符串。

此方法在 4.x 中已弃用,现已移除。所有以前用于编码 null 值的地方现在都会抛出 IllegalArgumentException

如果您在 Redis 请求中使用 null 值,则应停止这样做。要恢复以前的行为,您应手动将 null 值编码为 "null"。这适用于

  • Request.arg(String)

  • Request.arg(Buffer)

  • Request.arg(JsonArray):数组本身和单个元素

  • Request.arg(JsonObject):对象本身和单个元素

Redis 订阅自动转发到 Vert.x 事件总线

在 Vert.x 4.x 中,Redis 订阅会自动转发到事件总线,除非明确设置了消息处理程序(使用 RedisConnection.handler())。

现在情况不再如此。自 Vert.x 5 起,您始终必须注册消息处理程序。如果您仍希望将订阅消息转发到事件总线,则必须手动创建 EventBusHandler 实例并使用 RedisConnection.handler() 进行注册。

RedisConnection conn = ...;
conn.handler(EventBusHandler.create(vertx));
conn.send(Request.cmd(Command.SUBSCRIBE).arg("news"));

此外,EventBusHandler 不仅转发消息([p]message);它还转发订阅和取消订阅([p]subscribe[p]unsubscribe)。

RedisCluster.groupByNodes() 返回类型更改 + 代码生成更改

RedisCluster#groupByNodes() 方法过去返回 Future<List<List<Request>>>。由于此返回类型,RedisCluster 未标记为 @VertxGen

这在 Vert.x 5 中发生了变化。groupByNodes() 方法现在返回 Future<RequestGrouping>,并且整个接口都标记为 @VertxGen

此外,RequestResponseCommand 接口不再标记为 @VertxGen,而是标记为 @DataObject。这意味着代码生成 API(如 Vert.x Rx)的用户将不再使用生成的包装器;他们将使用核心 Vert.x Redis 接口。

RedisOptions 的 JSON 序列化/反序列化

RedisOptions 类有多种方法来配置 Redis 端点。这些方法仍然可用,但此类的 JSON 格式已更改,只包含一个规范字段:endpoints

如果您依赖 RedisOptions 对象的 JSON 格式,请注意 JSON 对象的 endpointconnectionStringconnectionStrings 成员不再被反序列化器识别,也不再被序列化器生成。请确保必要的信息存在于 endpoints 成员中。

Options addEndpoint/setEndpoint 替换

RedisOptions#addEndpointRedisOptions#setEndpointRedisOptions#addConnectionStringRedisOptions#setConnectionString 替换。

// 4.x
options.setEndpoint(location);

// 4.x
options.setConnectionString(location);

Vert.x RabbitMQ 客户端

4.x RabbitMQ 客户端库提供了 RabbitMQ API 的高级抽象,但不幸的是,这使得一些 RabbitMQ 用法变得不可能。这意味着 5.0 RabbitMQ 客户端库是完全重写的,具有非常不同的 API。

建立连接

4.x RabbitMQ 客户端库使用单个 RabbitMQClient 封装连接和通道,而 5.0 客户端库则将这两者分开处理,并且每个连接可以有多个通道。

5.0 RabbitMQChannel 的 API 与 4.x RabbitMQClient 最接近。

// 4.x
    RabbitMQOptions config = new RabbitMQOptions();
    // full amqp uri
    config.setUri("amqp://xvjvsrrc:VbuL1atClKt7zVNQha0bnnScbNvGiqgb@brokerhost/vhost");
    RabbitMQClient client = RabbitMQClient.create(vertx, config);

    // Connect
    client.start(asyncResult -> {
      if (asyncResult.succeeded()) {
        logger.info("RabbitMQ successfully connected!");
      } else {
        logger.warning("Failed to connect to RabbitMQ: {0}", asyncResult.cause().getMessage());
      }
    });

// 5.0
    RabbitMQOptions config = new RabbitMQOptions();
    config.setUri("amqp://brokerhost/vhost");
    config.setConnectionName(this.getClass().getSimpleName());
    config.setUser("guest");
    config.setPassword("guest");

    RabbitMQClient.connect(vertx, config)
            .compose(connection -> {
              RabbitMQChannelBuilder builder = connection.createChannelBuilder();
              return builder.openChannel();
            })
            .onSuccess(channel -> logger.info("Channel opened: {0}", channel.getChannelId()))
            .onFailure(ex -> logger.warning("Failed to connect to RabbitMQ: {0}", ex))
            ;

连接建立回调

一个具有自动重连功能的异步 RabbitMQ 客户端必须提供一种在通道可用之前创建交换机和队列的方法。在 4.x 库中,这是通过添加到 RabbitMQClient 的单个 connectionEstablishedCallback 完成的;对于 5.0 库,这是通过 channelOpenHandler 完成的,该处理程序必须在通道打开之前声明。

4.x 的 connectionEstablishedCallback 传入 RabbitMQClient,而 5.0 库在调用 channelOpenHandler 时 RabbitMQChannel 尚未建立,因此它传入原始的 com.rabbitmq.client.Channel。channelOpenHandler 在阻塞处理程序内部调用。

// 4.x
    RabbitMQClient client = RabbitMQClient.create(vertx, config);
    client.addConnectionEstablishedCallback(promise -> {
                client.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, EXCHANGE_DURABLE, EXCHANGE_AUTO_DELETE)
                    .compose(v -> {
                      return client.queueDeclare(QUEUE_NAME, QUEUE_DURABLE, QUEUE_EXCLUSIVE, QUEUE_AUTO_DELETE);
                    })
                    .compose(declareOk -> {
                      return client.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
                    })
                    .onComplete(promise);
    });

// 5.0
    RabbitMQClient.connect(vertx, config)
            .compose(connection -> {
              return connection.createChannelBuilder()
                      .withChannelOpenHandler(chann -> {
                        chann.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, EXCHANGE_DURABLE, EXCHANGE_AUTO_DELETE, null);
                        chann.queueDeclare(QUEUE_NAME, QUEUE_DURABLE, QUEUE_EXCLUSIVE, QUEUE_AUTO_DELETE, null);
                        chann.queueBind(QUEUE_NAME, EXCHANGE_NAME, "", null);
                      })
                      .openChannel();
            })
            ;

消费

5.0 库的 RabbitMQChannel 对象暴露了 basicConsume 方法,但建议使用 RabbitMQConsumer 以 Vert.x ReadStream 的形式提供消息。

除非每条消息都能同步处理而没有任何阻塞调用,否则消费者中可能会同时有多个消息在处理中。使用 RabbitMQ QOS 限制客户端接收的消息数量非常重要。

注意使用 STRING_MESSAGE_CODEC 在调用回调之前将消息体转换为字符串。

// 4.x
    client.basicConsumer(QUEUE_NAME, rabbitMQConsumerAsyncResult -> {
      if (rabbitMQConsumerAsyncResult.succeeded()) {
        RabbitMQConsumer mqConsumer = rabbitMQConsumerAsyncResult.result();
        mqConsumer.handler(message -> {
          System.out.println("Got message: " + message.body().toString());
        });
      }
    });

// 5.0
    connection.createChannelBuilder()
            .withQos(0, 10)
            .createConsumer(RabbitMQChannelBuilder.STRING_MESSAGE_CODEC
                    , QUEUE_NAME
                    , null
                    , new RabbitMQConsumerOptions()
                    , (consumer, message) -> {
                      System.out.println("Got message: " + message.body());
                      return message.basicAck();
                    });

发布

RabbitMQ 为消息提供两个选项:它可以保证消费者最多接收一次消息,或者它可以保证消费者至少接收一次消息。前者是默认选项,除了调用 basicPublish 之外不需要任何操作,但已发布的消息可能会丢失且根本不会传递。

为了保证消息被接收,发布者必须等待 RabbitMQ 的确认——如果该确认在与代理的连接断开之前没有到达,发布者必须在代理返回时重新发送消息。

Vert.x RabbitMQ 库提供了一个 RabbitMQPublisher,以简化确认的异步处理。

// 4.x
    Map<String, JsonObject> messages = ...
    RabbitMQPublisher publisher = RabbitMQPublisher.create(vertx, client, options);

    publisher.getConfirmationStream().handler(conf -> {
      if (conf.isSucceeded()) {
        messages.remove(conf.getMessageId());
      }
    });

    messages.forEach((k,v) -> {
      com.rabbitmq.client.BasicProperties properties = new AMQP.BasicProperties.Builder()
              .messageId(k)
              .build();
      publisher.publish(EXCHANGE_NAME, ROUTING_KEY, properties, v.toBuffer());
    });

    // Wait for messages to be empty


// 5.0
    Map<String, JsonObject> messages = ...
    RabbitMQClient.connect(vertx, config)
            .compose(connection -> {
              return connection.createChannelBuilder()
                      .createPublisher(EXCHANGE_NAME
                              , RabbitMQChannelBuilder.JSON_OBJECT_MESSAGE_CODEC
                              , new RabbitMQPublisherOptions().setResendOnReconnect(true)
                      );
            })
            .compose(publisher -> {
              List<Future<Void>> futures = new ArrayList<>(messages.size());
              messages.forEach((k,v) -> {
                AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                        .messageId(k)
                        .build();
                futures.add(publisher.publish(ROUTING_KEY, properties, v));
              });

              return Future.all(futures);
            })
            .onSuccess(v -> logger.info("All message sent and confirmed"))
            .onFailure(ex -> logger.log(Level.SEVERE, "Failed: {0}", ex))
            ;

Vert.x Consul 客户端

io.vertx.ext.consul.AclToken 已被移除,应使用 io.vertx.ext.consul.token.AclToken

这些已弃用的 API 方法已被移除

  • Check#getNodeName(),应使用 Check#getNode()

  • ConsulClient#createAclToken(io.vertx.ext.consul.AclToken),应使用 createAclToken(io.vertx.ext.consul.token.AclToken)

  • ConsulClient#updateAclToken(io.vertx.ext.consul.AclToken),应使用 updateAclToken(String, io.vertx.ext.consul.token.AclToken)

  • ConsulClient#cloneAclToken(String),应使用 cloneAclToken(String, CloneAclTokenOptions)

  • ConsulClient#infoAclToken(String),应使用 readAclToken(String)

  • ConsulClient#destroyAclToken(String),应使用 deleteAclToken(String)

  • ConsulClient#listAclTokens(),应使用 getAclTokens()

Vert.x 健康检查

健康检查依赖项改进

以前,Vert.x 健康检查依赖于 Vert.x Web 和 Vert.x Auth。它现在只定义健康检查 API,健康检查路由处理程序已移至 Vert.x Web。

这导致导入声明中的包更改。

// 4.x
import io.vertx.ext.healthchecks.HealthCheckHandler;

// 5.0
import io.vertx.ext.web.healthchecks.HealthCheckHandler;

Vert.x 断路器

移除已弃用并计划移除的重试策略

带有 Java 函数参数的断路器重试策略在 4.x 中弃用后已移除。

应使用 RetryPolicy 函数式接口。

// 4.x
breaker.retryPolicy(retryCount -> 5);

// 5.0
breaker.retryPolicy((failure, retryCount) -> 5);

Vert.x MQTT

客户端选项将消息字符串 getter/setter 弃用移除

客户端选项的 will 消息 string getter/setter 已在 4.x 中弃用后移除。

应使用 Buffer 版本。

// 4.x
options.setWillMessage(str);

// 5.0
options.setWillMessageBytes(Buffer.buffer(str));

Vert.x 邮件客户端

移除已弃用的 MailConfig setKeyStore/setKeyStorePassword

移除已弃用的 MailConfig#setKeyStoreMailConfig#setKeyStorePassword 属性。

应使用 MailConfig#setTrustOptions。

// 4.x
options.setKeyStore(trustStorePath);
options.setKeyStorePassword(trustStorePassword);

// 5.0
options.setTrustOptions(new JksOptions().setPath(trustStorePath).setPassword(trustStorePassword));

Vert.x JUnit 5

移除已弃用的测试上下文 succeeding

应使用 succeedingThenComplete()succeeding(Handler)

// 4.x
someFuture.onComplete(testContext.succeeding());

// 5.0
someFuture.onComplete(testContex.succeedingThenComplete());

Vert.x 服务代理

ServiceAuthInterceptor 移除

应使用 AuthorizationInterceptor

// 4.x
new ServiceBinder(vertx)
   .addInterceptor(new ServiceAuthInterceptor()...)
   .register(SomeService.class, service);

// 5.0
new ServiceBinder(vertx)
   .addInterceptor(AuthorizationInterceptor.create(authorizationProvider)...)
   .register(SomeService.class, service);

ServiceBinder 函数式拦截器

ServiceBinder#addInterceptor(Function)ServiceBinder#addInterceptor(String, Function) 已被移除,取而代之的是带有 ServiceInterceptor 函数式接口的变体。

// 4.x
binder.addInterceptor(msg -> vertx.timer(10, TimeUnit.MILLISECONDS).map(msg));

// 5.0
binder.addInterceptor((vertx, interceptorContext, body) -> vertx.timer(10, TimeUnit.MILLISECONDS).map(body));

移除 ProxyHelper 工具类

ProxyHelper 工具类已被移除,取而代之的是 ServiceProxyBuilder / ServiceBinder 等效类。

// 4.x
ProxyHelper.registerService(MyService.class, vertx, service, "the-address");
MyService proxy = ProxyHelper.createProxy(MyService.class, vertx, "the-address");

// 5.0
new ServiceBinder(vertx)
  .setAddress("the-address")
  .register(MyService.class, service);
MyService proxy = new ServiceProxyBuilder(vertx)
  .setAddress("the-address")
  .build(MyService.class)

Vert.x 响应式扩展

数据对象更改

Vert.x 中一些历史上被 @VertxGen 注解并因此被认为是异步类型的类已被转换为数据对象。

因此,类似生成器的响应流将不再需要包装/解包此类型,从而避免不必要的分配。

这意味着这些对象不再被 Vert.x RX 包装,并且其类型包名将发生更改。

以下类已升级为数据对象

  • io.vertx.core.buffer.Buffer

  • io.vertx.core.net.HostAndPort

  • io.vertx.core.net.SocketAddress

  • io.vertx.core.net.SelfSignedCertificate

  • io.vertx.core.MultiMap

  • io.vertx.core.datagram.DatagramPacket

  • io.vertx.core.dns.MxRecord

  • io.vertx.core.dns.SrvRecord

  • io.vertx.core.file.FileProps

  • io.vertx.core.file.FileSystemProps

  • io.vertx.core.http.Cookie

  • io.vertx.core.http.HttpFrame

  • io.vertx.core.http.WebSocketFrame

  • io.vertx.core.json.JsonEvent

在上述所有类型中,Vert.x buffer 类型可能是影响最大的更改。

io.vertx.core.buffer.Buffer 历史上一直作为异步生成类型的一部分存在于 API 中,并用 @VertxGen 注解。它一直被响应流生成器包装/解包。

// 4.x
io.vertx.reactivex.core.buffer.Buffer buffer = rxApi.getBuffer();

// 5.0
io.vertx.core.buffer.Buffer buffer = rxApi.getBuffer();

// 4.x
stream.write(io.vertx.reactivex.core.buffer.Buffer.buffer("the-string"));

// 5.0
stream.write(io.vertx.core.buffer.Buffer.buffer("the-string"));

同样适用于其他提到的类型。

Vert.x Micrometer 指标

升级到 Micrometer 1.14

Micrometer 1.14 紧随 1.13 之后发布,如果您在代码中使用了 PrometheusMeterRegistry API,1.13 是一个重大变更版本。

请查看 Micrometer 的迁移指南

HTTP 客户端连接池指标

HTTP 客户端连接池指标现在以池类型 http 的通用连接池指标形式公开

  • vertx_http_client_queue_pendingvertx_pool_queue_pending

  • vertx_http_client_queue_time_secondsvertx_pool_queue_time_seconds

移除选项上的注册表设置

用于 MeterRegistry 的 micrometer 选项设置器已移除,取而代之的是新的 VertxBuilderMicrometerMetricsFactory

// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
 .setMetricsOptions(new MicrometerMetricsOptions()
   .setMicrometerRegistry(myRegistry)
   .setEnabled(true)));

// 5.0
Vertx vertx = Vertx.builder()
  .with(new VertxOptions()
    .setMetricsOptions(new MicrometerMetricsOptions()
    .setEnabled(true)))
  .withMetrics(new MicrometerMetricsFactory(myRegistry))
  .build();

移除 InfluxDB 选项线程数

VertxInfluxDbOptions#getNumThreadsVertxInfluxDbOptions#setNumThreads 不再使用。

// 4.x
influxDbOptions.setNumThreads(numThreads);

// 5.0

重命名指标选项请求标签提供者

VertxMicrometerMetricsOptions#setRequestTagsProviderVertxMicrometerMetricsOptions#getRequestTagsProvider 已移除,取而代之的是 VertxMicrometerMetricsOptions#setServerRequestTagsProviderVertxMicrometerMetricsOptions#getServerRequestTagsProvider

// 4.x
options.setRequestsTagsProvider(provider);

// 5.0
options.setServerRequestsTagsProvider(provider);

默认启用的指标标签变化

由于高基数风险,HTTP ROUTE 标签不再默认启用。

要启用它,您必须在启动时修改指标选项

options.addLabels(Label.HTTP_ROUTE);

POOL NAME 标签现在默认启用。

Vert.x Dropwizard 指标

HTTP 客户端连接池指标

HTTP 客户端连接池指标现在以通用连接池指标形式公开,池类型为 http,并以端点套接字地址命名。

  • endpoint.<host:port>.queue-delayqueue-delay

  • endpoint.<host:port>.queue-sizequeue-size

移除度量选项中设置度量注册表

用于 MetricsRegistry 的 dropwizard 选项设置器已被移除,取而代之的是新的 VertxBuilderDropwizardMetricsFactory

// 4.x
Vertx vertx = Vertx.vertx(new VertxOptions()
 .setMetricsOptions(new DropwizardMetricsOptions()
   .setMetricsRegistry(myRegistry)
   .setEnabled(true)));

// 5.0
Vertx vertx = Vertx.builder()
  .with(new VertxOptions()
    .setMetricsOptions(new DropwizardMetricsOptions()
    .setEnabled(true)))
  .withMetrics(new DropwizardMetricsFactory(myRegistry))
  .build();

Vert.x Json Schema

弃用 API 移除

在 Vert.x 5 中,已弃用的 JSON Schema API 已被移除。以前,每个 Draft 都有自己的 SchemaParser。现在您有一个 SchemaRepository,并且可以在选项中设置 Draft

// 4.x
JsonObject schemaJson = new JsonObject(...);
Schema schema = new Draft7SchemaParser(SchemaRouter.create(vertx, new SchemaRouterOptions())).parse(schemaJson , scope);
JsonObject jsonToValidate = new JsonObject(...);
schema.validateSync(jsonToValidate);

// 5.0
JsonObject schemaJson = new JsonObject(...);
SchemaRepository schemaRepo = SchemaRepository.create(new JsonSchemaOptions().setDraft(DRAFT7));
JsonObject jsonToValidate = new JsonObject(...);
OutputUnit result = schemaRepo.validator(JsonSchema.of(schemaJson)).validate(jsonToValidate);

if (result.getValid()) {
  // Successful validation
}

额外的错误类型

在 Vert.x 5 中,已为输出单元添加了额外的基本错误类型。

如果您正在构建自己的 OutputUnits,您现在还需要包含 OutputErrorType。这有助于确定失败的原因。

// 4.x
OutputUnit ou = new OutputUnit("instanceLocation", "absoluteKeywordLocation", "keywordLocation", "error");

// 5.0
// Available error types are current OutputErrorType.NONE, OutputErrorType.INVALID_VALID, OutputErrorType.MISSING_VALUE
OutputUnit ou = new OutputUnit("instanceLocation", "absoluteKeywordLocation", "keywordLocation", "error", OutputErrorType.INVALID_VALUE);

移除 SchemaType INT 常量

应使用 SchemaType#INTEGER

移除 ValidationException createException 方法

应使用具有相同签名的 ValidationException#create 替代方法。

Vert.x Hazelcast

升级到 Hazelcast 5.3

此版本包含了自 Hazelcast 4.2.8 以来许多安全修复。它需要 JDK 11 才能运行,这是 Vert.x 5 中最低要求的版本。

集群管理器也已使用 Hazelcast 5.4 和 Hazelcast 5.5 进行测试。但这些版本分别至少需要 JDK 17 和 JDK 21。因此,我们不能默认使用它们。

Vert.x Zipkin

升级到 Zipkin Brave 6

Zipkin Brave 6 是一个重大变更版本。

尽管如此,Vert.x 5 中的 Vert.x Zipkin API 没有变化。