Vert .x
?Vert.x框架基于事件和异步,依托于全异步Java服务器Netty,并扩展了不少其余特性,以其轻量、高性能、支持多语言开发html
Hello world
建立一个简单的项目https://start.vertx.io/ 无需添加任何依赖java
public class MainVerticle extends AbstractVerticle { @Override public void start(Promise<Void> startPromise) throws Exception { vertx.createHttpServer().requestHandler(req -> { req.response() .putHeader("content-type", "text/plain") .end("Hello from Vert.x!"); }).listen(8888, http -> { if (http.succeeded()) { startPromise.complete(); System.out.println("HTTP server started on port 8888"); } else { startPromise.fail(http.cause()); } }); }
这个代码第一眼看上去就很复杂,可是其实仔细分析一下,会感受其实很好理解web
大体就是Vert.x
建立了一个Http
的服务,并添加请求头和响应的内容,监听8888
的端口,当服务建立成功时输出HTTP server started on port 8888
shell
Run
下面两个命令很重要切记编程
打包 $ mvn package 运行 $ mvn exec:java HTTP server started on port 8888 一月 28, 2021 11:14:37 下午 io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer 信息: Succeeded in deploying verticle 访问 $ curl http://127.0.0.1:8888/ Hello from Vert.x!
web
项目添加Vert.x Web
依赖json
<dependency> <groupId>io.vertx</groupId> <artifactId>vertx-web</artifactId> </dependency>
public class MainVerticle extends AbstractVerticle { @Override public void start(Promise<Void> startPromise) throws Exception { // 建立一个路由 Router router = Router.router(vertx); // 在每一个路径和HTTP方法中为全部传入请求安装处理程序 router.route().handler(context -> { // 获取请求的地址 String address = context.request().connection().remoteAddress().toString(); // Get the query parameter "name" MultiMap queryParams = context.queryParams(); String name = queryParams.contains("name") ? queryParams.get("name") : "unknown"; // Write a json response context.json( new JsonObject() .put("name", name) .put("address", address) .put("message", "Hello " + name + " connected from " + address) ); }); // Create the HTTP server vertx.createHttpServer() // Handle every request using the router(使用路由器处理每一个请求) .requestHandler(router) // Start listening .listen(8888) // Print the port .onSuccess(server -> System.out.println( "HTTP server started on port " + server.actualPort() ) ); } }
访问 $ curl http://127.0.0.1:8888/ {"name":"unknown","address":"127.0.0.1:3402","message":"Hello unknown connected from 127.0.0.1:3402"} $ curl http://127.0.0.1:8888?name=shaojie {"name":"shaojie","address":"127.0.0.1:3605","message":"Hello shaojie connected from 127.0.0.1:3605"}
Router
是Vert.x-Web的核心概念之一。它是保持零个或多个的对象 Routes
。服务器
路由器接收一个HTTP请求,并找到该请求的第一个匹配路由,而后将请求传递到该路由。app
路由能够具备与之关联的处理程序,该处理程序而后接收请求。而后,您能够对请求进行处理,而后结束请求或将其传递给下一个匹配的处理程序。框架
建立一个简单的路由:curl
HttpServer server = vertx.createHttpServer(); Router router = Router.router(vertx); router.route().handler(ctx -> { HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end("Hello World from Vert.x-Web!"); }); server.requestHandler(router).listen(8080);
当Vert.x-Web决定将请求路由到匹配的路由时,它将在的实例中传递该路由的处理程序RoutingContext
。路由能够具备不一样的处理程序,您可使用 handler
若是您未在处理程序中结束响应,则应进行调用,next
以便其余匹配的路由能够处理请求(若是有)。
Route route = router.route("/some/path/"); route.handler(ctx -> { HttpServerResponse response = ctx.response(); // 启用分块响应,由于咱们将在执行其余处理程序时添加数据。仅一次且仅当多个处理程序进行输出时才须要这样作 response.setChunked(true); response.write("route1\n"); // 延迟5秒后呼叫下一条匹配路线 ctx.vertx().setTimer(5000, tid -> ctx.next()); }); route.handler(ctx -> { HttpServerResponse response = ctx.response(); response.write("route2\n"); // 延迟5秒后呼叫下一条匹配路线 ctx.vertx().setTimer(5000, tid -> ctx.next()); }); route.handler(ctx -> { HttpServerResponse response = ctx.response(); response.write("route3"); // Now end the response ctx.response().end(); });
$ curl http://127.0.0.1:8080/some/path/ route1 route2 route3
在上面的示例route1
中,将响应写入响应,而后在5秒钟后将route2
其写入响应,而后在5秒钟后将route3
其写入响应,并结束响应。(注意,全部这些都在没有任何线程阻塞的状况下发生。)
处理程序很是强大,由于它们容许您构建很是复杂的应用程序。对于简单的响应,例如,直接从vert.x API返回异步响应,路由器包括处理程序的快捷方式,以确保:
router .get("/some/path") // 此处理程序将确保将响应序列化为json,并将内容类型设置为“application/json” .respond( ctx -> Future.succeededFuture(new JsonObject().put("hello", "world"))); router .get("/some/path") // 这个处理程序将确保Pojo被序列化为json 内容类型设置为“application/json” .respond( ctx -> Future.succeededFuture(new Pojo()));
$ curl http://127.0.0.1:8080/some/path/ {"hello":"world"}
可是,若是提供的函数调用write
或,您也能够将其用于非JSON响应end
:
router .get("/some/path") .respond( ctx -> ctx .response() .putHeader("Content-Type", "text/plain") .end("hello world!")); router .get("/some/path") // 在这种状况下,处理程序确保链接已经结束 .respond( ctx -> ctx .response() .setChunked(true) .write("Write some text..."));
$ curl http://127.0.0.1:8080/some/path/ hello world! $ curl http://127.0.0.1:8080/some/path/ Write some text...
Route route = router.route().path("/some/path/"); route.handler(ctx -> { // 此处理程序将被如下请求路径调用: // `/some/path/` // `/some/path//` // but not: // `/some/path` 路径的结束斜杠使其严格 // `/some/path/subdir` HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end("/some/path/"); }); // 不以斜杠结束的路径不严格 后面的斜杠是可选的 它们能够任意匹配 Route route2 = router.route().path("/some/path"); route2.handler(ctx -> { // 此处理程序将被如下请求路径调用: // `/some/path` // `/some/path/` // `/some/path//` // but not: // `/some/path/subdir` HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end("/some/path"); });
Route route = router.route().path("/some/path/*"); route.handler(ctx -> { // 此处理程序将被如下请求路径调用: // `/some/path/`, e.g. // `/some/path/` // `/some/path/subdir` // `/some/path/subdir/blah.html` // but not: // `/some/path` 该路径是严格的,由于它以斜杠结束 // `/some/bath` HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end("/some/path/*"); });
Route route = router.route(HttpMethod.POST, "/some/path/"); route.handler(ctx -> { // 对于以/some/path/开头的URI路径的任何POST请求,都会调用此处理程序 HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end("method--/some/path/"); });
get
、 post
、put
和delete
等以HTTP方法名称命名
router .get("/some/path") .respond( ctx -> ctx .response() .putHeader("Content-Type", "text/plain") .end("hello world!"));
若是要指定一个路由将匹配多个HTTP方法,则能够method
屡次调用:
Route route = router.route().method(HttpMethod.POST).method(HttpMethod.PUT); route.handler(ctx -> {});
若是要建立须要自定义HTTP动词的应用程序(例如WebDav
服务器),则能够指定自定义动词
Route route = router.route() .method(HttpMethod.valueOf("MKCOL")) .handler(ctx -> { // 任何MKCOL请求都将调用此处理程序 });
参考 处理请求并调用下一个处理程序
若是要覆盖路由的默认顺序,可使用order
,指定一个整数值。
路由在建立时被分配一个与添加到路由器的顺序相对应的顺序,第一个路由编号0
,第二个路由编号1
,依此类推。
经过指定路线的顺序,您能够覆盖默认顺序。订单也能够是负数,例如,若是您要确保在路线编号以前评估一条路线0
。
router .route("/some/path/") .order(1) .handler(ctx -> { HttpServerResponse response = ctx.response(); response.write("route1\n"); // Now call the next matching route ctx.next(); }); router .route("/some/path/") .order(0) .handler(ctx -> { HttpServerResponse response = ctx.response(); // 启用分块响应,由于咱们将在执行其余处理程序时添加数据。 // 仅一次且仅当多个处理程序进行输出时才须要这样作。 response.setChunked(true); response.write("route2\n"); // Now call the next matching route ctx.next(); }); router .route("/some/path/") .order(2) .handler(ctx -> { HttpServerResponse response = ctx.response(); response.write("route3"); // Now end the response ctx.response().end(); });
$ curl http://127.0.0.1:8080/some/path/ route2 route1 route3
关于路由得东西太多,后面单独整理一期,单独研究一下,刚开始学习的话,仍是先会用比较好
router .route(HttpMethod.POST, "/catalogue/products/:productType/:productID/") .handler(ctx -> { String productType = ctx.pathParam("productType"); String productID = ctx.pathParam("productID"); HttpServerResponse response = ctx.response(); response.putHeader("content-type", "text/plain"); response.end(productType + "--" + productID); });
$ curl -X POST http://127.0.0.1:8080/catalogue/products/String/123/ String--123
若是对编程感兴趣,请关注个人我的博客 https://www.lzmvlog.top/
本文由博客一文多发平台 OpenWrite 发布!