Vert.x Web之Router
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 中標準的 HttpServerRequest
和HttpServerResponse
,還包含了各種用於簡化 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