文章
问答
冒泡
Ⅱ vert.x的路由Router

当vert.x 工程顺利运行起来后,如果是一个web工程,通常会去写个接口测试下。官方的工程中,是一个默认的http服务,而实际使用中我们会需要一个路由,来根据不同的request信息交给不同的函数去处理,那么我们就需要一个router来干这个事。

vert.x 提供了 io.vertx.ext.web.Router 作为router的实现。
1.Router的基本使用

val server = vertx.createHttpServer()

val router = Router.router(vertx)

router.route().handler { ctx: RoutingContext ->

  val response = ctx.response()
  response.putHeader("content-type", "text/plain")

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

server.requestHandler(router).listen(8080){ http ->
  if (http.succeeded()) {
    startPromise.complete()
    println("HTTP server started on port 8888")
  } else {
    startPromise.fail(http.cause())
  }
}

2. Router处理多个handler
vert.x 支持多个handler,一个handler执行完了,到下一个继续执行。这里需要在第一个handler里讲response的 chunked设置为true

  val server = vertx.createHttpServer()

  val router = Router.router(vertx)
  val route = router.route()
  route.handler { ctx: RoutingContext ->
    val response = ctx.response()

    response.isChunked = true
    response.write("route1\n")

    ctx.vertx().setTimer(5000) { tid: Long? -> ctx.next() }
  }

  route.handler { ctx: RoutingContext ->
    val response = ctx.response()
    response.write("route2\n")

    ctx.vertx().setTimer(5000) { tid: Long? -> ctx.next() }
  }

  route.handler { ctx: RoutingContext ->
    val response = ctx.response()
    response.write("route3")

    // Now end the response
    ctx.response().end()
  }
  server.requestHandler(router).listen(8888){ http ->
    if (http.succeeded()) {
      startPromise.complete()
      println("HTTP server started on port 8888")
    } else {
      startPromise.fail(http.cause())
    }
  }
}


输出如下

0


3. 简单返回Json格式
在restful接口中,我们大部分时候,只需要返回一个json对象,vert.x  Router提供了通过respond 来返回json 

route.respond {
  Future.succeededFuture(JsonObject().put("hello", "world"))
}
0

 

4.Router 对HttpMethod的支持
Router的route()函数提供了对HttpMthod的支持,可以直接作为入参

router.route(HttpMethod.GET,"/all")


同时,还提供了get(),post(),put(),delete()等方法

5.Router中传参与获取
5.1 path传参

router.get("/name/:name").respond {ctx->
  val name = ctx.pathParam("name")
  Future.succeededFuture(JsonObject().put("name", name))
}


5.2 query传参

router.get("/all").respond {ctx->
  val name = ctx.request().getParam("name")
  Future.succeededFuture(JsonArray().add(JsonObject().put("name", name)))
}
0


5.3 body 传参

router.post().handler(BodyHandler.create())
  .respond {
  val user = it.bodyAsJson.mapTo(User::class.java)
  Future.succeededFuture(user)
}
0


这里记得要加jackson的依赖

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.13.2.2</version>
</dependency>


否则会报如下错误

io.vertx.core.json.DecodeException: Mapping ms.demo.entity.User  is not available without Jackson Databind on the classpath


5.4 header传参

router.delete("/:id").respond {ctx->
  val token = ctx.request().getHeader("token")
  println(token)
  Future.succeededFuture<Void>()
}
0


6.嵌套路由
在使用的时候,我们一般会根据模块对接口添加公共前缀,统一处理,也就是我们常说的嵌套路由

val articleRouter = Router.router(vertx)
articleRouter.get("/all").respond {
  Future.succeededFuture(JsonArray().add(JsonObject().put("name", "三国演义")))
}

val router = Router.router(vertx)
router.mountSubRouter("/articles",articleRouter)
0

7. 执行阻塞方法
在vert.x中,默认都是非阻塞方法,那么如果我们确实有阻塞方法的需求怎么办呢?vert.x 提供了对应的解决方案
7.1 使用blockingHandler

router.get("/blocking1").blockingHandler {
  Thread.sleep(5000L)
  it.response().end()
}
0


7.2 executeBlocking 
如果不想使用blockingHandler 还可以在respond中使用executeBlocking

router.get("/blocking2").respond {
  it.vertx().executeBlocking<Any> { it ->
    Thread.sleep(5000L)
    it.complete()
  }
}
0

这样,就基本满足了vert.x restful 的基本使用需求了。更详细的可以看官方文档 https://vertx.io/docs/vertx-web/java/#_using_vert_x_web

vert.x

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读