Vert .x

什么是Vert .x

Vert.x框架基于事件和异步,依靠于全异步Java服务器Netty,并扩大了很多其余个性,以其轻量、高性能、反对多语言开发

Hello world

创立一个简略的我的项目https://start.vertx.io/ 无需增加任何依赖

public class MainVerticle extends AbstractVerticle {  @Override  public void start(Promise<Void> startPromise) throws Exception {    vertx.createHttpServer().requestHandler(req -> {      req.response()        .putHeader("content-type", "text/plain")        .end("Hello from Vert.x!");    }).listen(8888, http -> {      if (http.succeeded()) {        startPromise.complete();        System.out.println("HTTP server started on port 8888");      } else {        startPromise.fail(http.cause());      }    }); }

这个代码第一眼看上去就很简单,然而其实仔细分析一下,会感觉其实很好了解

大抵就是Vert.x创立了一个Http的服务,并增加申请头和响应的内容,监听8888的端口,当服务创立胜利时输入HTTP server started on port 8888

Run

上面两个命令很重要切记

打包$ mvn package运行$ mvn exec:javaHTTP server started on port 8888一月 28, 2021 11:14:37 下午 io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer信息: Succeeded in deploying verticle拜访$ curl http://127.0.0.1:8888/Hello from Vert.x!

web我的项目

增加Vert.x Web 依赖

<dependency>    <groupId>io.vertx</groupId>    <artifactId>vertx-web</artifactId></dependency>
public class MainVerticle extends AbstractVerticle {  @Override  public void start(Promise<Void> startPromise) throws Exception {   // 创立一个路由    Router router = Router.router(vertx);    // 在每个门路和HTTP办法中为所有传入申请装置处理程序    router.route().handler(context -> {      // 获取申请的地址      String address = context.request().connection().remoteAddress().toString();      // Get the query parameter "name"      MultiMap queryParams = context.queryParams();      String name = queryParams.contains("name") ? queryParams.get("name") : "unknown";      // Write a json response      context.json(        new JsonObject()          .put("name", name)          .put("address", address)          .put("message", "Hello " + name + " connected from " + address)      );    });    // Create the HTTP server    vertx.createHttpServer()      // Handle every request using the router(应用路由器解决每个申请)      .requestHandler(router)      // Start listening      .listen(8888)      // Print the port      .onSuccess(server ->        System.out.println(          "HTTP server started on port " + server.actualPort()        )      );  } }
拜访$ curl http://127.0.0.1:8888/{"name":"unknown","address":"127.0.0.1:3402","message":"Hello unknown connected from 127.0.0.1:3402"}$ curl http://127.0.0.1:8888?name=shaojie{"name":"shaojie","address":"127.0.0.1:3605","message":"Hello shaojie connected from 127.0.0.1:3605"}

Vert.x-Web基本概念

Router是Vert.x-Web的外围概念之一。它是放弃零个或多个的对象 Routes

路由器接管一个HTTP申请,并找到该申请的第一个匹配路由,而后将申请传递到该路由。

路由能够具备与之关联的处理程序,该处理程序而后接管申请。而后您能够对申请进行解决,而后完结申请或将其传递给下一个匹配的处理程序。

创立一个简略的路由:

HttpServer server = vertx.createHttpServer();Router router = Router.router(vertx);router.route().handler(ctx -> {    HttpServerResponse response = ctx.response();    response.putHeader("content-type", "text/plain");    response.end("Hello World from Vert.x-Web!");});server.requestHandler(router).listen(8080);

解决申请并调用下一个处理程序

当Vert.x-Web决定将申请路由到匹配的路由时,它将在的实例中传递该路由的处理程序RoutingContext。路由能够具备不同的处理程序,您能够应用 handler

如果您未在处理程序中完结响应,则应进行调用,next以便其余匹配的路由能够解决申请(如果有)。

Route route = router.route("/some/path/");route.handler(ctx -> {    HttpServerResponse response = ctx.response();    // 启用分块响应,因为咱们将在执行其余处理程序时增加数据。仅一次且仅当多个处理程序进行输入时才须要这样做    response.setChunked(true);    response.write("route1\n");    // 提早5秒后呼叫下一条匹配路线    ctx.vertx().setTimer(5000, tid -> ctx.next());});route.handler(ctx -> {    HttpServerResponse response = ctx.response();    response.write("route2\n");    // 提早5秒后呼叫下一条匹配路线    ctx.vertx().setTimer(5000, tid -> ctx.next());});route.handler(ctx -> {    HttpServerResponse response = ctx.response();    response.write("route3");    // Now end the response    ctx.response().end();});
$ curl http://127.0.0.1:8080/some/path/route1route2route3

在下面的示例route1中,将响应写入响应,而后在5秒钟后将route2其写入响应,而后在5秒钟后将route3其写入响应,并完结响应。(留神,所有这些都在没有任何线程阻塞的状况下产生。)

简略的回应

处理程序十分弱小,因为它们容许您构建非常复杂的应用程序。对于简略的响应,例如,间接从vert.x API返回异步响应,路由器包含处理程序的快捷方式,以确保:

  1. 响应以JSON返回。
  2. 如果解决处理程序时产生谬误,则返回正确的谬误。
  3. 如果序列化对JSON的响应时出错,则返回正确的谬误。
router  .get("/some/path")  // 此处理程序将确保将响应序列化为json,并将内容类型设置为“application/json”  .respond(    ctx -> Future.succeededFuture(new JsonObject().put("hello", "world")));router  .get("/some/path")  // 这个处理程序将确保Pojo被序列化为json 内容类型设置为“application/json”  .respond(    ctx -> Future.succeededFuture(new Pojo()));
$ curl http://127.0.0.1:8080/some/path/{"hello":"world"}

然而,如果提供的函数调用write或,您也能够将其用于非JSON响应end

router  .get("/some/path")  .respond(    ctx -> ctx      .response()        .putHeader("Content-Type", "text/plain")        .end("hello world!"));router  .get("/some/path")  // 在这种状况下,处理程序确保连贯曾经完结  .respond(    ctx -> ctx      .response()        .setChunked(true)        .write("Write some text..."));
$ curl http://127.0.0.1:8080/some/path/hello world!$ curl http://127.0.0.1:8080/some/path/Write some text...

路由

按确切门路路由

Route route = router.route().path("/some/path/");route.handler(ctx -> {    // 此处理程序将被以下申请门路调用:    // `/some/path/`    // `/some/path//`        // but not:    // `/some/path` 门路的完结斜杠使其严格    // `/some/path/subdir`    HttpServerResponse response = ctx.response();    response.putHeader("content-type", "text/plain");    response.end("/some/path/");});// 不以斜杠完结的门路不严格 前面的斜杠是可选的 它们能够任意匹配Route route2 = router.route().path("/some/path");route2.handler(ctx -> {    // 此处理程序将被以下申请门路调用:    // `/some/path`    // `/some/path/`    // `/some/path//`        // but not:    // `/some/path/subdir`    HttpServerResponse response = ctx.response();    response.putHeader("content-type", "text/plain");    response.end("/some/path");});

通过以某些内容结尾的门路进行路由

Route route = router.route().path("/some/path/*");route.handler(ctx -> {    // 此处理程序将被以下申请门路调用:    // `/some/path/`, e.g.    // `/some/path/`    // `/some/path/subdir`    // `/some/path/subdir/blah.html`    // but not:    // `/some/path` 该门路是严格的,因为它以斜杠完结    // `/some/bath`    HttpServerResponse response = ctx.response();    response.putHeader("content-type", "text/plain");    response.end("/some/path/*");});

通过HTTP办法路由

Route route = router.route(HttpMethod.POST, "/some/path/");route.handler(ctx -> {    // 对于以/some/path/结尾的URI门路的任何POST申请,都会调用此处理程序    HttpServerResponse response = ctx.response();    response.putHeader("content-type", "text/plain");    response.end("method--/some/path/");});

间接调用

getpostputdelete等以HTTP办法名称命名

router  .get("/some/path")  .respond(    ctx -> ctx      .response()        .putHeader("Content-Type", "text/plain")        .end("hello world!"));

如果要指定一个路由将匹配多个HTTP办法,则能够method 屡次调用:

Route route = router.route().method(HttpMethod.POST).method(HttpMethod.PUT);route.handler(ctx -> {});

如果要创立须要自定义HTTP动词的应用程序(例如WebDav服务器),则能够指定自定义动词

Route route = router.route()  .method(HttpMethod.valueOf("MKCOL"))  .handler(ctx -> {    // 任何MKCOL申请都将调用此处理程序  });

路线程序

参考 解决申请并调用下一个处理程序

如果要笼罩路由的默认程序,能够应用order,指定一个整数值。

路由在创立时被调配一个与增加到路由器的程序绝对应的程序,第一个路由编号0,第二个路由编号1,依此类推。

通过指定路线的程序,您能够笼罩默认程序。订单也能够是正数,例如,如果您要确保在路线编号之前评估一条路线0

 router      .route("/some/path/")      .order(1)      .handler(ctx -> {        HttpServerResponse response = ctx.response();        response.write("route1\n");        // Now call the next matching route        ctx.next();      });    router      .route("/some/path/")      .order(0)      .handler(ctx -> {        HttpServerResponse response = ctx.response();        // 启用分块响应,因为咱们将在执行其余处理程序时增加数据。        // 仅一次且仅当多个处理程序进行输入时才须要这样做。        response.setChunked(true);        response.write("route2\n");        // Now call the next matching route        ctx.next();      });    router      .route("/some/path/")      .order(2)      .handler(ctx -> {        HttpServerResponse response = ctx.response();        response.write("route3");        // Now end the response        ctx.response().end();      });
$ curl http://127.0.0.1:8080/some/path/route2route1route3

对于路由得货色太多,前面独自整顿一期,独自钻研一下,刚开始学习的话,还是先会用比拟好

捕捉门路参数

router    .route(HttpMethod.POST, "/catalogue/products/:productType/:productID/")    .handler(ctx -> {        String productType = ctx.pathParam("productType");        String productID = ctx.pathParam("productID");        HttpServerResponse response = ctx.response();        response.putHeader("content-type", "text/plain");        response.end(productType + "--" + productID);    });
$ curl -X POST http://127.0.0.1:8080/catalogue/products/String/123/String--123

如果对编程感兴趣,请关注我的集体博客 https://www.lzmvlog.top/

本文由博客一文多发平台 OpenWrite 公布!