zoukankan      html  css  js  c++  java
  • 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
    ");
    
      // 5 秒后调用下一个处理器
      routingContext.vertx().setTimer(5000, tid -> routingContext.next());
    });
    
    Route route2 = router.route("/some/path/").handler(routingContext -> {
    
      HttpServerResponse response = routingContext.response();
      response.write("route2
    ");
    
      // 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 向响应里写入了数据并结束了响应。

      注意,所有发生的这些没有线程阻塞。

    下面看一个route自写的例子

    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());
                }
            });
    
        }
    }

    BodyHandler类:

    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   得到:"成功!"

    并输出如下:

    我是第一个打印!
    我是第二个打印!
    我是第三个打印!
    我是第四个打印!

  • 相关阅读:
    算法与设计模式
    Python开源应用系统
    ASP.NET MVC配置Redis服务
    常用3个框架
    Visual Studio 2015 编译错误 File 的值+乱码的解决方法
    SQL Server2008 R2命令行启动及停止SQL服务的方法
    Linux Shell查看物理CPU个数、核数、逻辑CPU个数
    SQL SERVER 2008R2 执行大脚本文件时,管理工具提示“内存不足”的解决方法
    MVC中未能加载程序集System.Web.Http/System.Web.Http.WebHost
    Windows10中启用原来的Windows照片查看器方法
  • 原文地址:https://www.cnblogs.com/heqiyoujing/p/9757925.html
Copyright © 2011-2022 走看看