Vert.X初探(一)

1 篇文章 0 订阅

一、Vert.X是什么

        Vert.x框架基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性,以其轻量、高性能、支持多语言开发而备受开发者青睐。Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。

  • Event Loop:即事件循环,是由Vert.x启动的事件处理线程,也是Vert.x项目对外开放的入口,Vert.x由此接收请求事件。一个Vert.x有一个或多个事件循环线程组成,线程最大数量为主机有效的CPU核数。
  • Event Loop Vertical:事件的业务处理线程,存在于Event Loop中,用于处理非阻塞短任务。
  • Worker Vertical : 事件的业务处理线程,用于处理长任务阻塞任务。
  • Event Bus:即事件总线,是Vert.x事件模型中最核心的部分,所有的事件都经由事件总线进行分发,包括Vertical之间的通信事件。
  • Vert.x Module : Vert.x项目模块,一个应用通常由多个模块组成,每个模块一般包含多个Vertical。

二、依赖引入

        <!-- vertx -->
        <vertx.version>4.5.7</vertx.version>      

        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-core</artifactId>
            <version>${vertx.version}</version>
        </dependency>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-codegen</artifactId>
            <version>${vertx.version}</version>
        </dependency>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-web</artifactId>
            <version>${vertx.version}</version>
        </dependency>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-auth-common</artifactId>
            <version>${vertx.version}</version>
        </dependency>
        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-rx-java</artifactId>
            <version>${vertx.version}</version>
        </dependency>

三、使用示例

3.1 创建HttpServer及路由Router

@Slf4j
public class SimpleRouter extends AbstractVerticle {

    @Override
    public void start() {

        // 创建HttpServer
        HttpServer server = vertx.createHttpServer();

        // 创建路由对象
        Router router = Router.router(vertx);

        // 监听/index地址,不限制HTTP请求方式
        router.route("/index").handler(request -> request.response().end("INDEX SUCCESS"));

        // route方式,限制HTTP请求方式为GET
        router.route(HttpMethod.GET, "/get-route-index").handler(request -> request.response().end("get-route-index SUCCESS"));

        // 限制HTTP请求方法为POST
        router.post("/post-demo").handler(request -> request.response().end("POST SUCCESS"));

        // 限制HTTP请求方法为GET
        router.get("/get-demo").handler(request -> request.response().end("GET SUCCESS"));

        // Mount the handler for all incoming requests at every path and HTTP method
        router.route("/json-demo").handler(requestHandler -> {
            // Get the address of the request
            String address = requestHandler.request().connection().remoteAddress().toString();
            // Get the query parameter "name"
            MultiMap queryParams = requestHandler.queryParams();
            String name = queryParams.contains("name") ? queryParams.get("name") : "unknown";
            // Write a json response
            requestHandler.json(
                new JsonObject()
                    .put("name", name)
                    .put("address", address)
                    .put("message", "Hello " + name + " connected from " + address)
            );
        });

        // Capturing path parameters, more than HTTP method
        router.route("/catalogue/products/:productType/:productId").method(HttpMethod.POST).method(HttpMethod.GET)
            .handler(requestHandler -> {
                String productType = requestHandler.pathParam("productType");
                String productId = requestHandler.pathParam("productId");
                requestHandler.json(
                    new JsonObject()
                        .put("productType", productType)
                        .put("productId", productId)
                );
            });

        // 把请求交给路由处理
        server.requestHandler(router);
        server.listen(8080).onSuccess(handle ->
            log.info("HTTP server started on port {}", handle.actualPort())
        );
    }
}

然后通过HTTP请求调用即可,例如:localhost:8080/catalogue/products/123/abc

3.2 响应结果设置格式

HttpServer server = vertx.createHttpServer();

Router router = Router.router(vertx);

router.route().handler(requestHandler -> {
  HttpServerResponse response = requestHandler.response();
  response.putHeader("content-type", "text/plain");


  response.end("Hello World from Vert.x-Web!");
});

server.requestHandler(router).listen(8080);

3.3 使用阻塞处理程序

router.route().blockingHandler(ctx -> {

  service.doSomethingThatBlocks();

  ctx.next();
});

        如果你需要从阻塞处理程序中处理多部分表单数据,你必须首先使用非阻塞处理程序来调用setExpectMultipart(true)。

router.post("/some/endpoint").handler(ctx -> {
  ctx.request().setExpectMultipart(true);
  ctx.next();
}).blockingHandler(ctx -> {
  // ... 处理你的业务
});

3.4 通过以某物开头的路径进行路由

Route route = router.route().path("/some/path/*");

route.handler(ctx -> {
  // `/some/path/`, 

  // `/some/path/`
  // `/some/path/a`
  // `/some/path/a/b.html`
});

3.5 路径参数

3.5.1 占位符方式

        // Capturing path parameters, more than HTTP method
        router.route("/catalogue/products/:productType/:productId").method(HttpMethod.POST).method(HttpMethod.GET)
            .handler(requestHandler -> {
                String productType = requestHandler.pathParam("productType");
                String productId = requestHandler.pathParam("productId");
                requestHandler.json(
                    new JsonObject()
                        .put("productType", productType)
                        .put("productId", productId)
                );
            });

3.5.2 使用正则表达式捕获路径参数

Route route = router.routeWithRegex(".*foo");

// This regular expression matches paths that start with something like:
// "/foo/bar" - where the "foo" is captured into param0 and the "bar" is
// captured into param1
route.pathRegex("\\/([^\\/]+)\\/([^\\/]+)").handler(ctx -> {

  String productType = ctx.pathParam("param0");
  String productID = ctx.pathParam("param1");

  // Do something with them...
});

3.6 正则表达式路由

3.6.1 路径或路由指定

Route route = router.route().pathRegex(".*foo");

route.handler(ctx -> {

  // This handler will be called for:

  // /some/path/foo
  // /foo
  // /foo/bar/wibble/foo
  // /bar/foo

  // But not:
  // /bar/wibble
});

        也可以在创建路由时指定正则表达式:

Route route = router.routeWithRegex(".*foo");

route.handler(ctx -> {

  // This handler will be called same as previous example

});

3.6.2 使用命名捕获组

 命名捕获组被映射到与组同名的路径参数

router
  .routeWithRegex("\\/(?<productType>[^\\/]+)\\/(?<productID>[^\\/]+)")
  .handler(ctx -> {

    String productType = ctx.pathParam("productType");
    String productID = ctx.pathParam("productID");

    // Do something with them...
  });

3.7 HTTP方法路由

3.7.1 匹配特定方式路由

Route route = router.route().method(HttpMethod.POST);

route.handler(ctx -> {

  // This handler will be called for any POST request

});

或者

Route route = router.route(HttpMethod.POST, "/some/path/");

route.handler(ctx -> {
  // This handler will be called for any POST request
  // to a URI path starting with /some/path/
});

或者

router.get().handler(ctx -> {

  // Will be called for any GET request

});

router.get("/some/path/").handler(ctx -> {

  // Will be called for any GET request to a path
  // starting with /some/path

});

router.getWithRegex(".*foo").handler(ctx -> {

  // Will be called for any GET request to a path
  // ending with `foo`

});

3.7.2 多个HTTP方式

        // Capturing path parameters, more than HTTP method
        router.route("/catalogue/products/:productType/:productId").method(HttpMethod.POST).method(HttpMethod.GET)
            .handler(requestHandler -> {
                String productType = requestHandler.pathParam("productType");
                String productId = requestHandler.pathParam("productId");
                requestHandler.json(
                    new JsonObject()
                        .put("productType", productType)
                        .put("productId", productId)
                );
            });

3.8 路由排序

3.8.1 默认排序

        默认情况下,按照添加顺序排序

router
  .route("/some/path/")
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    // enable chunked responses because we will be adding data as
    // we execute over other handlers. This is only required once and
    // only if several handlers do output.
    response.setChunked(true);

    response.write("route1\n");

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .handler(ctx -> {

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

    // Now call the next matching route
    ctx.next();
  });

router
  .route("/some/path/")
  .handler(ctx -> {

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

    // Now end the response
    ctx.response().end();
  });

输出

route1
route2
route3

3.8.2 指定排序

        如果两个匹配的路由具有相同的order值,那么它们将按照添加的顺序被调用。

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();
    // enable chunked responses because we will be adding data as
    // we execute over other handlers. This is only required once and
    // only if several handlers do output.
    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();
  });

输出

route2
route1
route3

3.8.3 指定顺序为last

可以直接指定最后 last

router
  .route("/some/path/")
  .last()
  .handler(ctx -> {

    HttpServerResponse response = ctx.response();
    response.write("route last\n");

    // Now call the next matching route
    ctx.next();
  });
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值