原文及更多文章請見個人博客:http://heartlifes.com
vert.x重要概念介紹:
在第2偏筆記中,我們寫了第一個vert.x的hello world代碼,這里,我們把代碼中用到的幾個重要概念解釋下。
Vertx基類:
Vertx類,是所有vert.x代碼的入口,官方代碼注釋為:
The entry point into the Vert.x Core API.
即該類是所有vert.x core包API的總入口,簡單理解就是,所有核心功能的API,都需要該類去調用,所有的核心功能也都需要該類提供環境上下文。
HttpServer:
官方注釋:
An HTTP and WebSockets server
http/https/websockets服務器,vert.x發布restful服務,不需要tomcat提供servlet容器,它自己就是一台性能強大的web服務器,並且原生支持負載均衡,后面我們會講到。
Router類:
先看官方代碼注釋:
A router receives request from an HttpServer and routes it to the first matching Route that it contains. A router can contain many routes.
Router類可以理解為一個路由器,他接收httpserver帶來的請求,並將不同的請求分發到不同的路由中,如果簡單對比一下spring mvc的話,可以將router理解為spring mvc中的dispatcher。
route:
route代表一條路由,同樣,對比spring mvc,相當於spring中的@RequestMapping,他指定了restful api的請求接口路徑,並將其交給handler來處理該條路由。
Handler:
首先來看官方代碼注釋:
Specify a request handler for the route. The router routes requests to handlers depending on whether the various criteria such as method, path, etc match. There can be only one request handler for a route. If you set this more than once it will overwrite the previous handler.
handler處理具體的路由請求,字面上講就是處理某個具體的restful api。他與httpserver,router,route的關系可以用如下流程表示:
來自httpserver的request請求-->交由路由器做分發處理-->路由器匹配到具體的路由規則-->路由到最終的handler去處理請求
vert.x默認提供了很多處理器,包括但不局限於以下:
AuthHandler 處理權限校驗支持
BodyHandler 提供所有請求上下文
CookieHandler 提供cookie支持
SessionHandler 提供session支持
RoutingContext:
官方代碼注釋:
Represents the context for the handling of a request in Vert.x-Web.
很簡單,請求上下文,可以理解為servlet中的httprequest和httpresponse
Verticle:
A verticle is a piece of code that can be deployed by Vert.x.
verticle是vert.x中,可被部署運行的最小代碼塊,可以理解為一個verticle就是一個最小化的業務處理引擎。
verticle被發布部署后,會調用其內部的start方法,開始業務邏輯處理,完成后會調用stop方法,對該代碼塊執行銷毀動作
vert.x發布restufl api
新建類:RestServer,代碼如下
package com.heartlifes.vertx.demo.simple;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
public class RestServer extends AbstractVerticle {
public static void main(String[] args) {
// 獲取vertx基類
Vertx vertx = Vertx.vertx();
// 部署發布rest服務
vertx.deployVerticle(new RestServer());
}
// 重寫start方法,加入我們的rest服務處理邏輯
@Override
public void start() throws Exception {
// 實例化一個路由器出來,用來路由不同的rest接口
Router router = Router.router(vertx);
// 增加一個處理器,將請求的上下文信息,放到RoutingContext中
router.route().handler(BodyHandler.create());
// 處理一個post方法的rest接口
router.post("/post/:param1/:param2").handler(this::handlePost);
// 處理一個get方法的rest接口
router.get("/get/:param1/:param2").handler(this::handleGet);
// 創建一個httpserver,監聽8080端口,並交由路由器分發處理用戶請求
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
// 處理post請求的handler
private void handlePost(RoutingContext context) {
// 從上下文獲取請求參數,類似於從httprequest中獲取parameter一樣
String param1 = context.request().getParam("param1");
String param2 = context.request().getParam("param2");
if (isBlank(param1) || isBlank(param2)) {
// 如果參數空,交由httpserver提供默認的400錯誤界面
context.response().setStatusCode(400).end();
}
JsonObject obj = new JsonObject();
obj.put("method", "post").put("param1", param1).put("param2", param2);
// 申明response類型為json格式,結束response並且輸出json字符串
context.response().putHeader("content-type", "application/json")
.end(obj.encodePrettily());
}
// 邏輯同post方法
private void handleGet(RoutingContext context) {
String param1 = context.request().getParam("param1");
String param2 = context.request().getParam("param2");
if (isBlank(param1) || isBlank(param2)) {
context.response().setStatusCode(400).end();
}
JsonObject obj = new JsonObject();
obj.put("method", "get").put("param1", param1).put("param2", param2);
context.response().putHeader("content-type", "application/json")
.end(obj.encodePrettily());
}
private boolean isBlank(String str) {
if (str == null || "".equals(str))
return true;
return false;
}
}
執行代碼,打開瀏覽器,輸入以下接口
http://localhost:8080/get/1/2
http://localhost:8080/post/1/2
處理session代碼示例:
package com.heartlifes.vertx.demo.simple;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.Session;
import io.vertx.ext.web.handler.CookieHandler;
import io.vertx.ext.web.handler.SessionHandler;
import io.vertx.ext.web.sstore.LocalSessionStore;
public class SessionServer extends AbstractVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new SessionServer());
}
@Override
public void start() throws Exception {
Router router = Router.router(vertx);
// 增加cookies處理器,解碼cookies,並將其放到context上下文中
router.route().handler(CookieHandler.create());
// 增加session處理器,為每次用戶請求,維護一個唯一的session,這里使用內存session,后面會講分布式的session存儲
router.route().handler(
SessionHandler.create(LocalSessionStore.create(vertx)));
router.route().handler(routingContext -> {
// 從請求上下文獲取session
Session session = routingContext.session();
Integer count = session.get("count");
if (count == null)
count = 0;
count++;
session.put("count", count);
routingContext.response()
.putHeader("content-type", "text/html")
.end("total visit count:" + session.get("count"));
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
}
處理cookies代碼示例:
package com.heartlifes.vertx.demo.simple;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.ext.web.Cookie;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.CookieHandler;
public class CookieServer extends AbstractVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new CookieServer());
}
@Override
public void start() throws Exception {
Router router = Router.router(vertx);
router.route().handler(CookieHandler.create());
router.route().handler(
routingContext -> {
Cookie cookie = routingContext.getCookie("testCookie");
Integer c = 0;
if (cookie != null) {
String count = cookie.getValue();
try {
c = Integer.valueOf(count);
} catch (Exception e) {
c = 0;
}
c++;
}
routingContext.addCookie(Cookie.cookie("testCookie",
String.valueOf(c)));
routingContext.response()
.putHeader("content-type", "text/html")
.end("total visit count:" + c);
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
}