Vert.x Web 是一系列用於基於 Vert.x 構建 Web 應用的構建模塊。html
Vert.x Web 的大多數特性被實現爲了處理器(Handler),所以您隨時能夠實現您本身的處理器。咱們預計隨着時間的推移會有更多的處理器被實現。web
<dependency> <groupId>io.vertx</groupId> <artifactId>vertx-web</artifactId> <version>3.4.2</version> </dependency>
HttpServer server = vertx.createHttpServer(); server.requestHandler(request -> { // 全部的請求都會調用這個處理器處理 HttpServerResponse response = request.response(); response.putHeader("content-type", "text/plain"); // 寫入響應並結束處理 response.end("Hello World!"); }); server.listen(8080);
Router
是 Vert.x Web 的核心概念之一。它是一個維護了零或多個 Route
的對象。json
Router 接收 HTTP 請求,並查找首個匹配該請求的 Route
,而後將請求傳遞給這個 Route
。api
Route
能夠持有一個與之關聯的處理器用於接收請求。您能夠經過這個處理器對請求作一些事情,而後結束響應或者把請求傳遞給下一個匹配的處理器。服務器
如下是一個簡單的路由示例:app
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。post
和上文同樣,咱們建立了一個 HTTP 服務器,而後建立了一個 Router
。在這以後,咱們建立了一個沒有匹配條件的 Route
,這個 route 會匹配全部到達這個服務器的請求。spa
以後,咱們爲這個 route
指定了一個處理器,全部的請求都會調用這個處理器處理。線程
調用處理器的參數是一個 RoutingContext
對象。它不只包含了 Vert.x 中標準的 HttpServerRequest
和HttpServerResponse
,還包含了各類用於簡化 Vert.x Web 使用的東西。code
每個被路由的請求對應一個惟一的 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
向響應裏寫入了數據並結束了響應。
注意,全部發生的這些沒有線程阻塞。
public class FirstMain extends AbstractVerticle { private static Logger logger = LoggerFactory.getLogger(FirstMain.class); public void start() { HttpServer server = vertx.createHttpServer(); Router router = Router.router(vertx); router.get("/hang/some").handler(routingContext -> { //指定get方法 // 全部的請求都會調用這個處理器處理 HttpServerResponse response = routingContext.response(); response.putHeader("content-type", "text/plain"); // 寫入響應並結束處理 response.end("Hello World from Vert.x-Web!"); }); router.route("/hang/all").handler(routingContext -> { // 全部的請求都會調用這個處理器處理 HttpServerResponse response = routingContext.response(); response.putHeader("content-type", "text/plain"); // 寫入響應並結束處理 response.end("Hello World !"); }); router.route("/hang/put").handler(BodyHandler::getStr); // router.route("/static/*").handler(StaticHandler.create()); //處理請求並調用下一個處理器 router.route(HttpMethod.POST,"/hang/add").handler(BodyHandler::getStr_1);//OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, PATCH, OTHER router.route("/hang/add").handler(BodyHandler::getStr_2); router.route("/hang/add").handler(BodyHandler::getStr_3); router.route("/hello").blockingHandler(BodyHandler.bodyHandler()::getStr_4, false); server.requestHandler(router::accept).listen(8080); } public static void main(String[] args) { // Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40)); // vertx.deployVerticle(FirstMain.class.getName()); // System.out.println("vertx......啓動"); Vertx.clusteredVertx(new VertxOptions(), res->{ if (res.succeeded()) { res.result().deployVerticle(FirstMain.class.getName()); logger.info("success start!" ); System.out.println("success start!" ); } else { logger.info("Failed: " + res.cause()); } }); } }
public class BodyHandler { // private Vertx vertx; private static BodyHandler bodyHandler = new BodyHandler(); public Logger logger = LoggerFactory.getLogger(BodyHandler.class); public static BodyHandler bodyHandler() { return bodyHandler; } public static void getStr(RoutingContext rc){ rc.response().end("Hello world! 我!"); } public static void getStr_1(RoutingContext rc){ HttpServerResponse response = rc.response(); // 因爲咱們會在不一樣的處理器裏寫入響應,所以須要啓用分塊傳輸,僅當須要經過多個處理器輸出響應時才須要 response.setChunked(true); response.write("我"); rc.next(); // 5 秒後調用下一個處理器 // rc.vertx().setTimer(5000, tid -> rc.next()); } public static void getStr_2(RoutingContext rc){ HttpServerResponse response = rc.response(); response.write("和"); rc.next(); } public static void getStr_3(RoutingContext rc){ HttpServerResponse response = rc.response(); response.write("你"); rc.response().end(); } public void getStr_4(RoutingContext rc){ ObjectMapper om = new ObjectMapper(); if ("1".equals("1")) { getOrder("1", res -> { if (res.succeeded()) { try { rc.response().putHeader("Content-type", "application/json; charset=UTF-8"); rc.response().end(om.writeValueAsString(res.result())); System.out.println("我是第四個打印!"); } catch (JsonProcessingException e) { e.printStackTrace(); } }else{ rc.response().setStatusCode(500) .putHeader("Content-type", "application/json; charset=UTF-8") .end((Buffer) new JsonObject().put("status", 0).put("des", "fali")); } }); System.out.println("我是第一個打印!"); } } private void getOrder(String orderId, Handler<AsyncResult<String>> handler){ Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(40)); vertx.<String>executeBlocking(future -> { try { Thread.sleep(1); System.out.println("我是第二個打印!"); future.complete("成功!"); } catch (InterruptedException e) { e.printStackTrace(); } },false, res->{ if (res.succeeded()) { System.out.println("我是第三個打印!"); handler.handle(Future.succeededFuture(res.result())); } else { handler.handle(Future.failedFuture(res.cause())); } }); } }
訪問 http://localhost:8080//hang/some 獲得:Hello World from Vert.x-Web!
訪問 http://localhost:8080//hang/all 獲得:Hello World !
訪問 http://localhost:8080//hang/put 獲得:Hello world! 我!
訪問 http://localhost:8080/hang/add 獲得:我和你 (post方式)
訪問 http://localhost:8080/helo 獲得:"成功!"
並輸出以下:
我是第一個打印!我是第二個打印!我是第三個打印!我是第四個打印!