1. 程式人生 > >Vert.x Web之Router

Vert.x Web之Router

\n accept handler 阻塞 中標 -- 隨著 clas next

  Vert.x Web 是一系列用於基於 Vert.x 構建 Web 應用的構建模塊。

  Vert.x Web 的大多數特性被實現為了處理器(Handler),因此您隨時可以實現您自己的處理器。我們預計隨著時間的推移會有更多的處理器被實現。

使用 Vert.x Web

  

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

回顧 Vert.x Core 的 HTTP 服務端

HttpServer server = vertx.createHttpServer();

server.requestHandler(request -> {

  // 所有的請求都會調用這個處理器處理
  HttpServerResponse response = request.response();
  response.putHeader("content-type", "text/plain");

  // 寫入響應並結束處理
  response.end("Hello World!");
});

server.listen(
8080);

Vert.x Web 的基本概念

Router 是 Vert.x Web 的核心概念之一。它是一個維護了零或多個 Route 的對象。

  Router 接收 HTTP 請求,並查找首個匹配該請求的 Route,然後將請求傳遞給這個 Route

  Route 可以持有一個與之關聯的處理器用於接收請求。您可以通過這個處理器對請求做一些事情,然後結束響應或者把請求傳遞給下一個匹配的處理器。

  以下是一個簡單的路由示例:

HttpServer server = vertx.createHttpServer();

Router router = Router.router(vertx);

router.route().handler(routingContext 
-> { // 所有的請求都會調用這個處理器處理 HttpServerResponse response = routingContext.response(); response.putHeader("content-type", "text/plain"); // 寫入響應並結束處理 response.end("Hello World from Vert.x-Web!"); }); server.requestHandler(router::accept).listen(8080);

  做了和上文使用 Vert.x Core 實現的 HTTP 服務器基本相同的事情,只是這一次換成了 Vert.x Web。

  和上文一樣,我們創建了一個 HTTP 服務器,然後創建了一個 Router。在這之後,我們創建了一個沒有匹配條件的 Route,這個 route 會匹配所有到達這個服務器的請求。

  之後,我們為這個 route 指定了一個處理器,所有的請求都會調用這個處理器處理。

  調用處理器的參數是一個 RoutingContext 對象。它不僅包含了 Vert.x 中標準的 HttpServerRequestHttpServerResponse,還包含了各種用於簡化 Vert.x Web 使用的東西。

  每一個被路由的請求對應一個唯一的 RoutingContext,這個實例會被傳遞到所有處理這個請求的處理器上。

處理請求並調用下一個處理器

  當 Vert.x Web 決定路由一個請求到匹配的 route 上,它會使用一個 RoutingContext 調用對應處理器。

  如果您不在處理器裏結束這個響應,您需要調用 next 方法讓其他匹配的 Route 來處理請求(如果有)。

  您不需要在處理器執行完畢時調用 next 方法。您可以在之後您需要的時間點調用它:

Route route1 = router.route("/some/path/").handler(routingContext -> {

  HttpServerResponse response = routingContext.response();
  // 由於我們會在不同的處理器裏寫入響應,因此需要啟用分塊傳輸
  // 僅當需要通過多個處理器輸出響應時才需要
  response.setChunked(true);

  response.write("route1\n");

  // 5 秒後調用下一個處理器
  routingContext.vertx().setTimer(5000, tid -> routingContext.next());
});

Route route2 = router.route("/some/path/").handler(routingContext -> {

  HttpServerResponse response = routingContext.response();
  response.write("route2\n");

  // 5 秒後調用下一個處理器
  routingContext.vertx().setTimer(5000, tid ->  routingContext.next());
});

Route route3 = router.route("/some/path/").handler(routingContext -> {

  HttpServerResponse response = routingContext.response();
  response.write("route3");

  // 結束響應
  routingContext.response().end();
});

  在上述的例子中,route1 向響應裏寫入了數據,5秒之後 route2 向響應裏寫入了數據,再5秒之後 route3 向響應裏寫入了數據並結束了響應。

  註意,所有發生的這些沒有線程阻塞。

Vert.x Web之Router