Vert.x 簡介

REST
Remote
0
12:19 PM · Dec 01 ,2025

1. 概述

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

我們首先將涵蓋工具包的基準概念,然後逐步過渡到 HTTP 服務器,最後構建 RESTfull 服務。

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 應用程序的神經系統。

由於其反應性,Verticle 在接收到消息或事件時保持休眠狀態。Verticle 通過事件總線與其他 Verticle 進行通信。消息可以是字符串到複雜對象。

消息處理應理想情況下是異步的,消息被排隊到事件總線上,並返回到發送方。稍後它被從偵聽 Verticle 中取出。響應使用 Future callback 方法。

5. 簡單的 Vert.x 應用程序

讓我們創建一個簡單的應用程序,其中包含一個 Verticle,並使用 vertx 實例進行部署。要創建我們的 Verticle,我們將擴展 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());
}

類似於地,我們可以覆蓋 AbstractVerticle 類中的 stop() 方法,該方法將在關閉 Verticle 時被調用:

@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("歡迎使用 Vert.x 介紹"));
      })
      .listen(config().getInteger("http.port", 9090), 
        result -> {
          if (result.succeeded()) {
              future.complete();
          } else {
              future.fail(result.cause());
          }
      });
}

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

最後,服務器綁定到一個端口,並且一個 AsyncResult<HttpServer> 處理程序被傳遞到 listen()方法,無論連接或服務器啓動是否成功,都使用 future.complete() future.fail()在任何錯誤的情況下。

請注意: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()方法中的 setup()方法中。

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

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

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

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

請注意:@BeforeClass setup() 方法接受 TestContext 參數。 這有助於我們控制和測試測試中的異步行為。 例如,verticle 部署是異步的,因此我們基本上不能測試任何內容,除非它已正確部署。

我們有一個 deployVerticle() 方法中的第二個參數,testContext.asyncAssertSuccess(). T 他的目的是要知道服務器是否已正確部署或是否發生任何失敗。 它等待 future.complete() 或 future.fail() 在服務器 verticle 中被調用。 在發生錯誤的情況下,它會失敗測試。

7. RESTful WebService

我們已經創建了一個 HTTP 服務器,現在讓我們使用它來託管一個 RESTful WebService。為了做到這一點,我們需要另一個 Vert.x 模塊,叫做 vertx-web。它提供了大量用於 Web 開發的附加功能,這些功能建立在 vertx-core 之上。

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

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

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

7.1. Router and Routes

讓我們為我們的 WebService 創建一個 router。這個 router 將會接收一個簡單的 GET 方法的請求,並使用 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));
}

一個 Router 在接收到請求時,會查找匹配的路由,並將請求傳遞給處理方法。 routes 具有與之關聯的處理方法,用於對請求執行某些操作。

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

在方法末尾,我們調用 response() 方法,該方法位於 routingContext 對象上,並設置了頭信息、設置了 HTTP 響應代碼,並使用 JSON 編碼的 article 對象結束響應。

7.2. Adding Router to Server

現在,讓我們將創建的 router 添加到 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. 包裝 Vert.x 應用程序為了將應用程序打包為可部署的 Java 存檔 (.jar),我們使用 Maven Shade 插件以及在 execution 標籤中的配置:

<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>

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

9. 結論

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

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

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

發佈 評論

Some HTML is okay.