Vert Core 为vertx-web模块提供了什么依赖?
先来看段最原始的 vert core 提供的http 开发示例:
首先,vertx 创建HttpServer,然后设置回调处理器hander,并传入request参数(request提供了大量方法,基本跟传统Serverlet Request类似),最后设置服务器监听端口。然后运行访问8080端口,页面显示“hello world”。
Vert 依赖core包提供socket 通信能力以及http协议的编码解码功能(core 包源码有具体实现),最后留给用户的只剩下处理器hander以及已经封装好数据的HttpServerRequest。所以vert.x web开发的重要关注点就在这两个东西,其中HttpServerRequest将贯穿整个web模块的始终。
上面示例,不管你访问后缀是多少,返回的结果都是一样的比如:http://localhost:8080/{x},x随便写什么。假如现在有个需求,需要根据不同的访问后缀返回对应的数据,怎么实现?首先我们要获取到用户访问的path,然后根据path去匹配结果,伪代码如下:
if(path 匹配 “path1”){
返回 “path1”;
}else if(path 匹配 “path2”){
返回 “path2”;
}......
path 哪来?HttpServerRequest提供了获取请求path的方法,这个类封装了所有用户请求行为,比如请求路径,参数,cookie等等。在看上面例子,回调处理hander,并且传入了HttpServerRequest参数,方法体就是用户需要实现的具体业务逻辑,比如操作数据库进行业务处理,然后返回结果给客户端等等。
回调函数是vert core 触发的,上层调用并不需要关心。大概流程:浏览器发送请求->vert core监听端口接收数据->http 协议解码,封装HttpServerRequest->触发回调函数,处理完返回结果->vert core http协议编码->返回结果到浏览器。
到目前为止,还没提到半点vertx-web的功能。也就是说没有vertx-web,vertx core也是完全可以开发web应用的,他们关系跟severlet和 spring mvc类似,后者是对前者的进一步封装,目的是为了简化开发,提高效率。
在回过头来看上面的伪代码,假如有几十个几百个请求后缀再加上业务逻辑代码,这样if else 的写下去,代码完全是一坨混杂在一起,直觉告诉你这样肯定是不行的。好在 core包提供了最为关键的一个类HttpServerRequest以及函数入口。
好啦,现在我们的处境是:客户端每次发送请求之后,我们都能获取到request,request里面完全封装了用户请求数据,比如请求方法,请求参数,请求路径等。获取到request之后,我们需要通过用户请求的path分别做相应的业务处理,我们肯定不会按照上面那样 if else的去判断区分。我们需要一个更“自动化”的东西,完成这些事,而我们只需关心自己的具体业务实现(spring mvc就做的很好)。在这样的驱动下,vertx-web也就登上历史的舞台了(当然,假如用的不爽,也完全可以自己写个web模块)。
额。。有点跑题了,现在来看下HttpServerRequest,它是个接口,在core包中有具体实现,request相关的类并不是vertx-web提供的,都在core里面的http包下。所以,request压根就不是 web模块中的源码。但这个类是core和web模块通信的桥廊,地位十分重要,所以也就在这Vert.x Web模块源码分析第一篇做个基本介绍,但不展开源码分析,因为这涉及到http编码解码等一系列东西,不在web模块分析的范畴。
HttpServerRequest可以理解为对http协议字段的功能性封装,每次用户发送请求,所有相关的请求行为全部会记录到HttpServerRequest,比如http 头部,host,parameter等等。具体可以参数api 文档。后续章节会涉及到HttpServerRequest部分接口,具体到时候在讲解。
PS:结束之前说个比较重要的类
在vert中有许都地方用到 Hander类,源码
@FunctionalInterface
public interface Handler
void handle(E event);
}
其中@FunctionalInterface是java8新加的一个注解,用于说明该接口是函数式接口
之前示例代码中的server.requestHandler()的参数就是具体实现。
server.requestHandler(request -> {
HttpServerResponse response = request.response();
response.putHeader("content-type","text/plain");
response.end("Hello World!");
});
因为Hander