Vertx 路由初体验

Posted Johnny屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vertx 路由初体验相关的知识,希望对你有一定的参考价值。

Vertx 路由初体验

上一篇 我们说了关于Vertx 入门的,简单介绍了下Vertx 并且搭建了一个 demo ,这一篇主要讲解一下 Vertx 的另外一个专门用于开发Web的 Vertx-Web 组件中的 路由的开发



回顾

回顾上一篇中,我们使用Vertx 创建了一个 最简单的Http服务,但是我们会发现 这个服务不管访问什么路径都会返回 Hello Vertx !!! 相同的返回,这肯定在正式项目中肯定行不通,本篇就来说关于路由 来处理不同的路由

/**
* @author johnny
* @create 2020-10-14 下午7:43
**/
public class VertxDemo {

   public static void main(String[] args) {
       Vertx vertx = Vertx.vertx();
//直接创建 服务器
       vertx.createHttpServer()
              .requestHandler(requestHandler -> {
                   //获取到 Response 直接返回消息
                   requestHandler.response().end("Hello Vertx !!!");
              })
               //监听在 8899 端口
              .listen(8899);
  }
}


访问 http://localhost:8899

可以看到 返回了 Hello Vertx!!!



Vertx-Web


Vert.x提供了Web开发组件vertx-web,提供了一堆Web开发中常用的功能。比如参数封装,路由,国际化,认证和授权,session和cookie以及模板等,可以非常方便的进行Vert.x Web开发。

本篇主要介绍Web开发中的路由功能,路由简单说就是把用户请求交给合适的处理器处理的组件。如下图所示

Vertx 路由初体验



1.路由开发


1.1 引入依赖

gradle 引入下面core 和 web

compile 'io.vertx:vertx-core:3.9.3'

//添加 vertx-web组件 来进行 web 开发 提供一些如 路由等
compile 'io.vertx:vertx-web:3.9.3'


1.2 创建一个 /hello 路由

public static void main(String[] args) {

   Vertx vertx = Vertx.vertx();
 
   HttpServer httpServer = vertx.createHttpServer();
   //创建路由
   Router router = Router.router(vertx);

//访问 /hello
   router.route("/hello").handler(requestHandler -> {
       requestHandler.response().end(" Hello Vertx Path : /hello ");
  });
  //将收到的请求交给 路由 router
  httpServer.requestHandler(router);
       httpServer.listen(8899);

}

上面代码就是 使用Vertx 创建一个Http服务 监听 8899端口 ,并且给Vertx 添加了一个 路由,把请求都交给路由处理,当请求来的时候 会进行路由匹配,找到对应的处理器来处理


访问  http://localhost:8899/hello   是不是很像springmvc的 RequestMapping("/hello")

Vertx 路由初体验



1.3 创建一个带通配符的路由

/some/path/foo.html and /some/path/otherdir/blah.css 都可以被匹配.

//带 通配符 get 请求
Route route = router.route().path("/some/path/*");

route.handler(routingContext -> {
 // This handler will be called for any path that starts with
 // `/some/path/`, e.g.

 // `/some/path/`
 // `/some/path/subdir`
 // `/some/path/subdir/blah.html`
 //
 // but not:
 // `/some/path` the path is strict because it ends with slash
 // `/some/bath`
});



1.4 获取请求参数

可以获取 ?name = Johnny 或者 /hello/:param 这种参数

通过 String name = request.getParam("name"); //根据request.getParam 获取请求参数

public static void main(String[] args) {

   Vertx vertx = Vertx.vertx();

   HttpServer httpServer = vertx.createHttpServer();
   //创建路由
   Router router = Router.router(vertx);

   //任意 请求方式
   router.route("/hello").handler(requestHandler -> {
       HttpServerRequest request = requestHandler.request();
       String name = request.getParam("name"); //根据request.getParam 获取请求参数

       requestHandler.response().end(" Hello Vertx path : /hello param : " + name);
  });
}

Post Get 都支持 因为我们没有指定是什么请求方式 下面会说



类似 SpringMVC的 @PathVariable获取 路径上的参数

Route route = router.route(HttpMethod.POST, "/catalogue/products/:producttype/:productid/");

route.handler(routingContext -> {

 String productType = routingContext.request().getParam("producttype");
 String productID = routingContext.request().getParam("productid");

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


1.5 获取请求头参数

有些时候需要 获取请求头的 数据, 通过 getHeader

//获取 post 方式中的 header
router.post("/post").blockingHandler(requestHandler -> {
   HttpServerRequest request = requestHandler.request();
 
   String header = request.getHeader("xxx-x");

   requestHandler.response().end(" Hello Vertx path : /post header : " + header);
});



1.6 提交 Post Json参数

注意一定要在 自己的handler 前面添加 一个 BodyHandler 否则会报错 ,很像SpringMvc的 @RequestBody


一般我们提交都会提交一个 Json对象通过 getBodyAsJson() 获取JsonObject

//如果不添加 BodyHandler.create() 则 无法 从 Post的 body体中 获取数据
//router.route().handler(BodyHandler.create());
router.route(HttpMethod.POST, "/postbody")
      .handler(requestHandler -> {
           JsonObject jsonObject = requestHandler.getBodyAsJson(); //获取jsonObject
           System.out.println(jsonObject);
           requestHandler.response().end("Hello Vertx jsonObject : " + jsonObject);
      });


注意 在处理json的时候 需要在我们的handler前面 添加一个 BodyHandler 否则不行!!!

添加BodyHandler



1.6  创建Rest风格的路由


前面的案例中 router.route 都是任意请求方式

如果我们想创建特定请求方式的 路由 通过


router.get("/list")
router.post("/update")
router.put("/save")
router.delete("/del")
 
//或者 使用 router 的重载方法 去指定 HttpMethod
 
router.route(HttpMethod.POST, "/post2").blockingHandler(requestHandler -> {
           HttpServerRequest request = requestHandler.request();
           String name = request.getParam("name");
           String header = request.getHeader("xxx-x");
           requestHandler.response().end(" Hello Vertx path : /post param : " + name + " header : " + header);
      });





2. 二级路由


当我们有很多路由 前缀都一样 ,可以抽取出来,作为二级路由 挂载到 主路由上,很像SpringMvc Controller上面标注 @RequestMapping(value = "/product")


public static void main(String[] args) {

   Vertx vertx = Vertx.vertx();

   Router router = Router.router(vertx);

   Router productRouter = Router.router(vertx);
   productRouter.get("/:id").handler(requestHandler -> {
       String id = requestHandler.request().getParam("id");
       requestHandler.response().end("get id : " + id);
  });

   productRouter.put("/:id").handler(requestHandler -> {
       String id = requestHandler.request().getParam("id");
       requestHandler.response().end("put id : " + id);
  });

   productRouter.delete("/:id").handler(requestHandler -> {
       String id = requestHandler.request().getParam("id");
       requestHandler.response().end("delete id : " + id);
  });
   // 挂载 二级路由 productRouter 到 router 主路由上
   router.mountSubRouter("/product", productRouter);

   vertx.createHttpServer()
          .requestHandler(router::accept)
          .listen(8899);

}


访问的时候 就是

get 请求 http://localhost:8899/product/1

put delete 一样



3. 路由顺序 Order


路由会被最前面的匹配到,所以可以通过 指定 order 来控制 顺序,order的值越小 越优先被匹配


详细看 案例 /api/main 会被第一个路由匹配,不会走到第二个 而 /index/main 因为设置了order 会被 第二个 路由匹配到

public static void main(String[] args) {

   Vertx vertx = Vertx.vertx();

   Router router = Router.router(vertx);


   //Vert.x进行路由匹配的规则非常简单,默认就是当匹配成功之后就不再继续匹配了
   // api/main 会被 /api/* 匹配到
   router.get("/api/*").handler(rc -> {
       rc.response().end("path : /api/*");
  });

   router.get("/api/main").handler(rc -> {
       rc.response().end("path : /api/main");
  });

   //2种方式 解决 匹配顺序问题 1.把路由顺序 调整一下 (这种肯定不是很合适) 2.使用 order 去控制

   //order控制 order 的值 越低 优先级越高
   router.get("/index/*").order(1)
          .handler(rc -> {
               rc.response().end("path : /index/*");
          });

   router.get("/index/main").order(-1)
          .handler(rc -> {
               rc.response().end("path : /index/main");
          });

   vertx.createHttpServer()
          .requestHandler(router::accept)
          .listen(8899);


}



总结

本篇主要讲了下 vertx-web 中提供的 路由的开发,包括基本的 路由匹配,获取路由参数,提交 Json参数, Rest风格的路由,二级路由 , 路由顺序 等等。。。






以上是关于Vertx 路由初体验的主要内容,如果未能解决你的问题,请参考以下文章

Vertx 初体验

路由初体验02

Vert.x初体验

Vert.x初体验

vs code初体验

vue3.0 Composition API 上手初体验 用路由循环,做个导航菜单