共计 7137 个字符,预计需要花费 18 分钟才能阅读完成。
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: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
依赖
<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/ | |
route1 | |
route2 | |
route3 |
在下面的示例 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/ | |
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 公布!