我们在前面的文章分析了Vertx核心单机部分的源码。今天轮到Vert.x-Web,由于Web的内容比较多,因此分为上下两部分。
- 上:分析Vert.x-Web核心类及其主要能力。
- 下:分析HttpServer的线程调度以及Web OpenAPI的工作原理
一个基本的VertxWeb代码片段如下:
fun main() {
val vertx = Vertx.vertx()
val router = Router.router(vertx)
router.get("/hello")
.handler {
ctx ->
println("哈哈哈,我好开心")
ctx.next()
}
.failureHandler(ErrorHandler.create())
val server = vertx.createHttpServer().requestHandler(router)
server.listen(8080)
}
上面创建了一个Http服务,暴露8080端口,并注册了一个path为hello,方法为GET的接口。上面涉及到Vert.x-Web的类有:Router、Route、RoutingContext、HttpServer。我们介绍前三个。
Router
Router
首先是Router接口,它主要有以下几个方面组成。
-
Router.router(vertx) 创建一个Router对象
-
routeXXX() 各种路由方法,可以根据路径、方法、媒体类型、正则表达式等各种方式路由,返回一个Route对象,用于指定处理器。
-
getRoutes() 获取所有route
-
clear() 清除所有Route
-
mountSubRouter() 挂载子router
-
exceptionHandler() 指定一个router级别的异常处理器,当handler中抛出异常时,它会捕获。但它不会影响正常业务逻辑。
但它目前已被废弃,应该使用errorHandler(),它对应的是500的错误
-
errorHandler(code, handler) 当发生特定错误码时会调用它。当RoutingContext失败(fail) 或 一些handler失败但没有写响应 或 handler中抛出了异常,都会调用它。需要注意的是它的500有特殊的意义,代表通用错误。
-
handleContext(context) 将一个RoutingContext传进来,当一个Router被挂载到某个route时会用:将该route的RoutingContext传入本router进行处理。
-
handleFailure(RoutingContext) 使用场景同上,处理失败
-
modifiedHandler(handler) 当本Router的Route发生变化时该方法会被触发。
首先说,Router只是Handler的子类,因此本质上还只是一个处理器,是被动调用的。
@VertxGen
public interface Router extends Handler<HttpServerRequest> {
... ...
RouterImpl
众多route生成方法的实现都大同小异,都是创建RouteImpl
public synchronized Route route(String path) {
state = state.incrementOrderSequence();
return new RouteImpl(this, state.getOrderSequence(), path);
}
另外一个重点是handle,既然Router是Handler的子类,因此本类最初被调用的一定是handle方法(在请求进来时调用)
@Override
public void handle(HttpServerRequest request) {
// 注意后面的next()调用,这很容易被看漏掉。
new RoutingContextImpl(null, this, request, state.getRoutes()).next();
}
啥也没干,就创建了一个RoutingContextImpl,并调用了next(),开启处理逻辑。
RouterState
一个RouterImpl包含一个RouterState,在初始化时创建,用于管理Router的状态
public RouterImpl(Vertx vertx) {
this.vertx = vertx;
this.state = new RouterState(this);
}
共有如下几种状态
- Route集合:Router内注册的Route全在这里
- errorHandler映射:失败的处理器,其中key对应的错误码,如400
- modifiedHandler:用于在Router发生变化时做出响应的处理器
private final Set<RouteImpl> routes;
private final Map<Integer, Handler<RoutingContext>> errorHand