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 获得:"成功!"
并输出以下:
我是第一个打印!我是第二个打印!我是第三个打印!我是第四个打印!