Vert .x
什么是Vert .x
?
Vert.x框架基于事件和异步,依靠于全异步Java服务器Netty,并扩大了很多其余个性,以其轻量、高性能、反对多语言开发
Hello world
创立一个简略的我的项目https://start.vertx.io/ 无需增加任何依赖
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()); } }); }
这个代码第一眼看上去就很简单,然而其实仔细分析一下,会感觉其实很好了解
大抵就是Vert.x
创立了一个Http
的服务,并增加申请头和响应的内容,监听8888
的端口,当服务创立胜利时输入HTTP server started on port 8888
Run
上面两个命令很重要切记
打包$ mvn package运行$ mvn exec:javaHTTP 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
依赖
<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"}
Vert.x-Web基本概念
Router
是Vert.x-Web的外围概念之一。它是放弃零个或多个的对象 Routes
。
路由器接管一个HTTP申请,并找到该申请的第一个匹配路由,而后将申请传递到该路由。
路由能够具备与之关联的处理程序,该处理程序而后接管申请。而后,您能够对申请进行解决,而后完结申请或将其传递给下一个匹配的处理程序。
创立一个简略的路由:
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/route1route2route3
在下面的示例route1
中,将响应写入响应,而后在5秒钟后将route2
其写入响应,而后在5秒钟后将route3
其写入响应,并完结响应。(留神,所有这些都在没有任何线程阻塞的状况下产生。)
简略的回应
处理程序十分弱小,因为它们容许您构建非常复杂的应用程序。对于简略的响应,例如,间接从vert.x API返回异步响应,路由器包含处理程序的快捷方式,以确保:
- 响应以JSON返回。
- 如果解决处理程序时产生谬误,则返回正确的谬误。
- 如果序列化对JSON的响应时出错,则返回正确的谬误。
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/*");});
通过HTTP办法路由
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/route2route1route3
对于路由得货色太多,前面独自整顿一期,独自钻研一下,刚开始学习的话,还是先会用比拟好
捕捉门路参数
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 公布!