知識庫 / REST RSS 訂閱

Vert.x 簡介

REST
HongKong
4
03:54 AM · Dec 06 ,2025

1. 概述

本文將討論 Vert.x,涵蓋其核心概念並使用它創建一個簡單的 RESTful Web 服務。

我們將首先介紹該工具包的核心概念,然後逐步過渡到 HTTP 服務器,最後構建 RESTful 服務。

2. 關於 Vert.x

Vert.x 是 Eclipse 開發團隊開源的、反應式和多語種軟件開發工具包

反應式編程是一種編程範式,與異步流相關聯,能夠響應任何變化或事件。

Vert.x 同樣使用事件總線,用於與應用程序的不同部分進行通信,並將事件異步地傳遞給處理程序,當處理程序可用時。

我們稱之為多語種,因為它支持 Java、Groovy、Ruby、Python 和 JavaScript 等多種 JVM 和非 JVM 語言

3. 安裝配置

要使用 Vert.x,我們需要添加 Maven 依賴項:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>3.9.15</version>
</dependency>

最新版本的依賴項可以在這裏找到:這裏

3. 虛擬實例

虛擬實例是 Vert.x 引擎執行的代碼片段。該工具包提供了許多可擴展和自定義的抽象虛擬實例類。

由於其多語言特性,虛擬實例可以編寫在任何受支持的語言中。一個應用程序通常由多個虛擬實例在同一 Vert.x 實例中運行,並通過事件總線進行互通信。

要創建 JAVA 虛擬實例,該類必須實現 io.vertx.core.Verticle 接口,或其任何子類。

4. 事件總線 (Event Bus)

它是任何 Vert.x 應用的神經系統。

由於其反應式特性,Vert.x 實例在接收到消息或事件時保持休眠狀態。Vert.x 實例通過事件總線與其他實例進行通信。消息可以是字符串到複雜對象,任何類型。

消息處理應儘可能異步進行。消息被排隊到事件總線上,控制權返回給發送者。稍後,它會被從監聽器 Vert.x 實例中取出。響應使用 Future callback 方法發送。

5. 簡單 Vert.x 應用程序

讓我們創建一個簡單的應用程序,其中包含一個 Vert.x 模塊,並使用 vertx 實例進行部署。 要創建我們的 Vert.x 模塊,我們將擴展 io.vertx.core.AbstractVerticle 類並覆蓋 start() 方法:

public class HelloVerticle extends AbstractVerticle {

    @Override
    public void start(Future<Void> future) {
        LOGGER.info("Welcome to Vertx");
    }
}

start() 方法將在 verticle 部署時由 vertx 實例調用。該方法接受 io.vertx.core.Future 作為參數,可用於發現 verticle 異步部署的狀態。

現在讓我們部署 verticle:

public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    vertx.deployVerticle(new HelloVerticle());
}

同樣,我們也可以覆蓋 stop() 方法來自 AbstractVerticle 類,這將會在垂直塊關閉時被調用:

@Override
public void stop() {
    LOGGER.info("Shutting down application");
}

6. HTTP 服務器

現在我們使用 verticle 啓動一個 HTTP 服務器:

@Override
public void start(Future<Void> future) {
    vertx.createHttpServer()
      .requestHandler(r -> r.response().end("Welcome to Vert.x Intro");
      })
      .listen(config().getInteger("http.port", 9090), 
        result -> {
          if (result.succeeded()) {
              future.complete();
          } else {
              future.fail(result.cause());
          }
      });
}

我們已覆蓋了 start() 方法以創建 HTTP 服務器,並將其附加到請求處理程序上。 requestHandler() 方法在服務器收到請求時每次都會被調用。

最後,服務器綁定到端口,並且使用 future.complete() future.fail() 在連接或服務器啓動成功或發生錯誤的情況下,將 AsyncResult<HttpServer> 處理程序傳遞給 listen() 方法。

請注意:config.getInteger() 方法正在讀取 HTTP 端口配置的值,該值從外部 conf.json 文件加載。

讓我們測試我們的服務器:

@Test
public void whenReceivedResponse_thenSuccess(TestContext testContext) {
    Async async = testContext.async();

    vertx.createHttpClient()
      .getNow(port, "localhost", "/", response -> {
        response.handler(responseBody -> {
          testContext.assertTrue(responseBody.toString().contains("Hello"));
          async.complete();
        });
      });
}

對於本次測試,我們使用 vertx-unit 結合 JUnit:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-unit</artifactId>
    <version>3.9.15</version>
    <scope>test</scope>
</dependency>

我們可以從這裏獲取最新版本。

Verticle 已部署並在 vertx 實例的 setup() 方法中:

@Before
public void setup(TestContext testContext) {
    vertx = Vertx.vertx();

    vertx.deployVerticle(SimpleServerVerticle.class.getName(), 
      testContext.asyncAssertSuccess());
}

同樣,vertx實例在@AfterClass tearDown()方法中被關閉:

@After
public void tearDown(TestContext testContext) {
    vertx.close(testContext.asyncAssertSuccess());
}

請注意,@BeforeClass setup() 方法接受一個 TestContext 參數。這有助於我們控制和測試測試中的異步行為。例如,Verticle部署是異步的,因此我們無法測試它是否正確部署。

我們有第二個參數傳遞給 deployVerticle() 方法,即 testContext.asyncAssertSuccess() 。它用於確定服務器是否已正確部署或是否發生任何錯誤。它會等待 future.complete() 或 future.fail() 在服務器 Verticle 中被調用。如果發生錯誤,則測試會失敗。

7. RESTful WebService

我們已經創建了一個 HTTP 服務器,現在將使用它來託管一個 RESTful WebService。為此,我們需要另一個 Vert.x 模塊,即 vertx-web。它為在 vertx-core 的基礎上進行 Web 開發提供了許多額外的功能。

讓我們將依賴項添加到我們的 pom.xml 中:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>3.9.15</version>
</dependency>

我們可以在這裏找到最新版本 這裏

7.1. 路由器路由

讓我們為我們的 WebService 創建一個 路由器。這個路由器將處理一個簡單的 GET 方法路由,以及 handler 方法 getArtilces()

Router router = Router.router(vertx);
router.get("/api/baeldung/articles/article/:id")
  .handler(this::getArticles);

getArticle() 方法是一個簡單的方法,它返回一個新的 Article 對象:

private void getArticles(RoutingContext routingContext) {
    String articleId = routingContext.request()
      .getParam("id");
    Article article = new Article(articleId, 
      "This is an intro to vertx", "baeldung", "01-02-2017", 1578);

    routingContext.response()
      .putHeader("content-type", "application/json")
      .setStatusCode(200)
      .end(Json.encodePrettily(article));
}

一個 路由器, 在接收到請求時,會查找匹配的路由並將其傳遞給後續處理。 路由中包含與該請求關聯的處理方法,用於對請求進行處理。

在我們的例子中,處理方法會調用 getArticle() 方法。 它接收 routingContext 對象作為參數,並從中提取路徑參數 id,然後創建一個包含該參數的 Article 對象。

在方法最後一部分,我們調用 response() 方法,該方法位於 routingContext 對象上,用於設置頭部、設置 HTTP 響應代碼,並使用 JSON 編碼的 Article 對象結束響應。

7.2. 將 路由器 添加到服務器

現在,讓我們將上一節中創建的 路由器 添加到 HTTP 服務器:

vertx.createHttpServer()
  .requestHandler(router::accept)
  .listen(config().getInteger("http.port", 8080), 
    result -> {
      if (result.succeeded()) {
          future.complete();
      } else {
          future.fail(result.cause());
      }
});

請注意,我們已將 requestHandler(router::accept) 添加到服務器。 這會指示服務器在接收到任何請求時,調用 accept() 函數,該函數屬於 router 對象。

現在,讓我們測試我們的 WebService:

@Test
public void givenId_whenReceivedArticle_thenSuccess(TestContext testContext) {
    Async async = testContext.async();

    vertx.createHttpClient()
      .getNow(8080, "localhost", "/api/baeldung/articles/article/12345", 
        response -> {
            response.handler(responseBody -> {
            testContext.assertTrue(
              responseBody.toString().contains("\"id\" : \"12345\""));
            async.complete();
        });
      });
}

8. 部署式 Java 存檔 (JAR) 包 Vert.x 應用程序

要將應用程序打包為部署式 Java 存檔 (JAR) 文件,我們使用 Maven Shade 插件以及在 <em execution</em>> 標籤中的配置:

<configuration>
    <transformers>
        <transformer 
          implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <manifestEntries>
                <Main-Class>io.vertx.core.Starter</Main-Class>
                <Main-Verticle>com.baeldung.SimpleServerVerticle</Main-Verticle>
            </manifestEntries>
        </transformer>
    </transformers>
    <artifactSet />
    <outputFile>
        ${project.build.directory}/${project.artifactId}-${project.version}-app.jar
    </outputFile>
</configuration>

manifestEntries 中,Main-Verticle 指示應用程序的啓動點,Main-Class 是一個 Vert.x 類,它創建了 vertx 實例並部署了 Main-Verticle

9. 結論

在本文檔中,我們探討了 Vert.x 工具包及其基本概念。演示瞭如何使用 Vert.x 創建 HTTP 服務器,以及如何使用 Vert.x 構建 RESTful Web 服務,並展示瞭如何使用 vertx-unit 進行測試。

最後,將應用程序打包為可執行的 JAR 文件。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.