一、Vert.x-web介绍
1、Vert.x-web基于Vert.x core,可以非常简单的构建web应用程序的功能集;
2、Yoke从Node.js中的Express框架和Ruby世界中的Sinatra获得灵感出来的一个基于Vert.x 2.x框架;
3、Vertx-web并不是容器,Vert.x-Web强在设计,内部功能并不是完全嵌入,你只需构建应用时只需使用你所需要的;
4、Vert.x-web可以创建经典的服务器侧Web应用程序、RESTfulweb应用程序、实时(服务器推送)Web应用,或者其他你要实现的某种web应用,应用的类型完全由你决定;
5、Vert.x-Web非常适合编写RESTful HTTP微服务,但是Vert.x不强制你这样编写应用程序
二、Vert.x-web包含的功能
- 路由(基于方法【get,post】,路径,等)
- 路径的正则表达式匹配
- 从路径中抽取参数
- 内容协商
- 请求体处理
- 请求和响应体大小限制
- Cookie解析与处理
- 多部分表单(指有表单域和上传的表单)
- 多部分文件上传
- 子路由器
- 会话支持——包括本地(粘滞会话)和集群(非粘滞)
- CORS(跨区域资源共享)支持
- 错误页处理
- Basic认证
- 基于认证的重定向
- JWt (Java Web Toolkit) 基本认证
- 用户/角色/权限认证
- favicon(指浏览器页面上的图标)处理
-
模板支持服务端渲染,支持下列模板引擎
Handlebars Jade MVEL Thymelea Apache FreeMarker
- 响应时间处理器
- 静态文件提供,包括缓存逻辑和目录列表
- 请求超时处理
- SockJS支持
- 事件总线桥
- CSRF虚拟跨站请求
- 虚拟主机
Vert.x-web的大多数特性被实现成处理器,所以要以自己编写。随着时间推移,会在vert.x-web中添加更多内容。我们将在此手册中讨认所有这些特性
三、Vert.x-web使用情况调查
下图为来自网络调查所得web框架排行榜:
可以看出Vert.x是仅次于spring MVC排名在第二位的框架,可见Vert.x的活跃程度已经很高了。
四、Vert.x-web简单例子
Vert.x-web本身包含功能很多,这里的例子只是通过Vert.x-web 基于java8(还有ruby、groovy、JavaScript等)实现简单的功能,详细例子可见:https://github.com/vert-x3/vertx-examples/tree/master/web-examples
简单Hello Word
public class Server extends AbstractVerticle {
public static void main(String[] args) {
Runner.runExample(Server.class);
}
@Override
public void start() throws Exception {
Router router = Router.router(vertx);
router.route().handler(routingContext -> {
routingContext.response().putHeader("content-type", "text/html").end("Hello World!");
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
}
页面展现:
简单rest微服务
public class SimpleREST extends AbstractVerticle {
public static void main(String[] args) {
Runner.runExample(SimpleREST.class);
}
private Map<String, JsonObject> products = new HashMap<>();
@Override
public void start() {
setUpInitialData();
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.get("/products/:productID").handler(this::handleGetProduct);
router.put("/products/:productID").handler(this::handleAddProduct);
router.get("/products").handler(this::handleListProducts);
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
private void handleGetProduct(RoutingContext routingContext) {
String productID = routingContext.request().getParam("productID");
HttpServerResponse response = routingContext.response();
if (productID == null) {
sendError(400, response);
} else {
JsonObject product = products.get(productID);
if (product == null) {
sendError(404, response);
} else {
response.putHeader("content-type", "application/json").end(product.encodePrettily());
}
}
}
private void handleAddProduct(RoutingContext routingContext) {
String productID = routingContext.request().getParam("productID");
HttpServerResponse response = routingContext.response();
if (productID == null) {
sendError(400, response);
} else {
JsonObject product = routingContext.getBodyAsJson();
if (product == null) {
sendError(400, response);
} else {
products.put(productID, product);
response.end();
}
}
}
private void handleListProducts(RoutingContext routingContext) {
JsonArray arr = new JsonArray();
products.forEach((k, v) -> arr.add(v));
routingContext.response().putHeader("content-type", "application/json").end(arr.encodePrettily());
}
private void sendError(int statusCode, HttpServerResponse response) {
response.setStatusCode(statusCode).end();
}
private void setUpInitialData() {
addProduct(new JsonObject().put("id", "prod3568").put("name", "Egg Whisk").put("price", 3.99).put("weight", 150));
addProduct(new JsonObject().put("id", "prod7340").put("name", "Tea Cosy").put("price", 5.99).put("weight", 100));
addProduct(new JsonObject().put("id", "prod8643").put("name", "Spatula").put("price", 1.00).put("weight", 80));
}
private void addProduct(JsonObject product) {
products.put(product.getString("id"), product);
}
}
页面展现: