一个Route对象可以包含零个或多个Route;
一个Route处理一个HTTP请求,找到第一个匹配请求路径,并传递参数给它。
该Route在接收请求后有关联的程序处理,可以处理、结束,或者传递给下一个匹配的程序处理。
举例:
HttpServer server = vertx.createHttpServer();
Router router =Router.router(vertx);
router.route().handler(routingContext ->{
// This handler will be called for every request
HttpServerResponse response = routingContext.response();
response.putHeader("content-type","text/plain");
// Write to the response and end it
response.end("Hello World from Vert.x-Web!");
});
server.requestHandler(router::accept).listen(8080);
RoutingContext
代表请求处理的上下文
提供了访问HttpServerRequest和HttpServerResponse
路由到处理程序会被丢弃
处理请求,并调用下一个请求:
Route route1 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
// enable chunked responses because we will be adding data as
// we execute over other handlers. This is only required once and
// only if several handlers do output.
response.setChunked(true);
response.write("route1\n");
// Call the next matching route after a 5 second delay
routingContext.vertx().setTimer(5000, tid -> routingContext.next());
});
Route route2 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
response.write("route2\n");
// Call the next matching route after a 5 second delay
routingContext.vertx().setTimer(5000, tid -> routingContext.next());
});
Route route3 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
response.write("route3");
// Now end the response
routingContext.response().end();
});
阻塞处理
router.route().blockingHandler(routingContext ->{
// Do something that might take some time synchronously
service.doSomethingThatBlocks();
// Now call the next handler
routingContext.next();
});
路由路径头
Route route = router.route().path("/some/path/*");
route.handler(routingContext ->{
// This handler will be called for any path that starts with
// `/some/path/`, e.g.
// `/some/path`
// `/some/path/`
// `/some/path/subdir`
// `/some/path/subdir/blah.html`
//
// but not:
// `/some/bath`
});
捕获参数
/catalogue/products/tools/drill123/
Route route = router.route(HttpMethod.POST,"/catalogue/products/:productype/:productid/");
route.handler(routingContext ->{
String productType = routingContext.request().getParam("producttype");
String productID = routingContext.request().getParam("productid");
// Do something with them...
});
HTTP方法路由
router.get().handler(routingContext ->{
// Will be called for any GET request
});
router.get("/some/path/").handler(routingContext ->{
// Will be called for any GET request to a path
// starting with /some/path
});
router.getWithRegex(".*foo").handler(routingContext ->{
// Will be called for any GET request to a path
// ending with `foo`
});
Route route = router.route().method(HttpMethod.POST).method(HttpMethod.PUT);
route.handler(routingContext ->{
// This handler will be called for any POST or PUT request
});
路由顺序
默认为增加顺序,顺序从0开始,order方法设置顺序
Route route1 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
// enable chunked responses because we will be adding data as
// we execute over other handlers. This is only required once and
// only if several handlers do output.
response.setChunked(true);
response.write("route1\n");
// Now call the next matching route
routingContext.next();
});
Route route2 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
response.write("route2\n");
// Now call the next matching route
routingContext.next();
});
Route route3 = router.route("/some/path/").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
response.write("route3");
// Now end the response
routingContext.response().end();
});
// Change the order of route2 so it runs before route1
route2.order(-1);
route1
route2
route3
基于MIME类型描述请求路由
使用comsumes
router.route().consumes("text/html").consumes("text/plain").handler(routingContext ->{
// This handler will be called for any request with
// content-type header set to `text/html` or `text/plain`.
});
router.route().consumes("text/*").handler(routingContext ->{
// This handler will be called for any request with top level type `text`
// e.g. content-type header set to `text/html` or `text/plain` will both match
});
router.route().consumes("*/json").handler(routingContext ->{
// This handler will be called for any request with sub-type json
// e.g. content-type header set to `text/json` or `application/json` will both match
});
基于MIME类型描述客户端可接受的路由
配置content-type
router.route().produces("application/json").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
response.putHeader("content-type","application/json");
response.write(someJSON).end();
});
router.route().produces("application/json").produces("text/html").handler(routingContext ->{
HttpServerResponse response = routingContext.response();
// Get the actual MIME type acceptable
String acceptableContentType = routingContext.getAcceptableContentType();
response.putHeader("content-type", acceptableContentType);
response.write(whatever).end();
});
上下文数据
routingContext包含所有处理请求生命周期中的所有数据。
使用routingContext.data访问数据图
router.get("/some/path").handler(routingContext ->{
routingContext.put("foo","bar");
routingContext.next();
});
router.get("/some/path/other").handler(routingContext ->{
String bar = routingContext.get("foo");
// Do something with bar
routingContext.response().end();
});
重路由
reroute
router.get("/some/path").handler(routingContext ->{
routingContext.put("foo","bar");
routingContext.next();
});
router.get("/some/path/B").handler(routingContext ->{
routingContext.response().end();
});
router.get("/some/path").handler(routingContext ->{
routingContext.reroute("/some/path/B");
});
子路由
/products/product1234
Router restAPI =Router.router(vertx);
restAPI.get("/products/:productID").handler(rc ->{
// TODO Handle the lookup of the product....
rc.response().write(productJSON);
});
restAPI.put("/products/:productID").handler(rc ->{
// TODO Add a new product...
rc.response().end();
});
restAPI.delete("/products/:productID").handler(rc ->{
// TODO delete the product...
rc.response().end();
});
Router mainRouter =Router.router(vertx);
// Handle static resources
mainRouter.route("/static/*").handler(myStaticHandler);
mainRouter.route(".*\\.templ").handler(myTemplateHandler);
mainRouter.mountSubRouter("/productsAPI", restAPI);
国际化
解析Accept-Language
头部使用acceptableLocales
方法
locale不存在,preferredLocale
会返回第一个元素
Route route = router.get("/localized").handler( rc ->{
// although it might seem strange by running a loop with a switch we
// make sure that the locale order of preference is preserved when
// replying in the users language.
for(Locale locale : rc.acceptableLocales()){
switch(locale.language()){
case"en":
rc.response().end("Hello!");
return;
case"fr":
rc.response().end("Bonjour!");
return;
case"pt":
rc.response().end("Olá!");
return;
case"es":
rc.response().end("Hola!");
return;
}
}
// we do not know the user language so lets just inform that back:
rc.response().end("Sorry we don't speak: "+ rc.preferredLocale());
});
默认404路由
路由不存在
错误处理
抛出异常或者指定http错误代码会被failureHandler捕获,
如果程序捕获了异常,不会被捕获,会抛出500错误代码。
Route route1 = router.get("/somepath/path1/");
route1.handler(routingContext ->{
// Let's say this throws a RuntimeException
thrownewRuntimeException("something happened!");
});
Route route2 = router.get("/somepath/path2");
route2.handler(routingContext ->{
// This one deliberately fails the request passing in the status code
// E.g. 403 - Forbidden
routingContext.fail(403);
});
// Define a failure handler
// This will get called for any failures in the above handlers
Route route3 = router.get("/somepath/*");
route3.failureHandler(failureRoutingContext ->{
int statusCode = failureRoutingContext.statusCode();
// Status code will be 500 for the RuntimeException or 403 for the other failure
HttpServerResponse response = failureRoutingContext.response();
response.setStatusCode(statusCode).end("Sorry! Not today");
});
请求体处理
BodyHandler允许获取请求体,限制大小,处理文件上传
router.route().handler(BodyHandler.create());
getBodyAsJson
,getBodyAsString
,getBody
.
限制大小:
过大则413 -Request Entity Too Large
表单属性合并
文件上传:
router.route().handler(BodyHandler.create());
router.post("/some/path/uploads").handler(routingContext ->{
Set<FileUpload> uploads = routingContext.fileUploads();
// Do something with uploads....
});
支持cookies处理
router.route().handler(CookieHandler.create());
操纵cookies
router.route().handler(CookieHandler.create());
router.route("some/path/").handler(routingContext ->{
Cookie someCookie = routingContext.getCookie("mycookie");
String cookieValue = someCookie.getValue();
// Do something with cookie...
// Add a cookie - this will get written back in the response automatically
routingContext.addCookie(Cookie.cookie("othercookie","somevalue"));
});
处理sessions
相关推荐
【Vert.x 4 核心手册中文版】深入解析 Vert.x 是一个轻量级、高性能的反应式应用开发框架,适用于 Java 和其他多种语言。它的核心组件小巧且灵活,允许开发者只使用需要的部分,并能无缝嵌入到现有的应用程序中,...
Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。 Event Loop:即事件循环,...
本教程将探讨如何使用Vert.x和Spring Boot结合来开发一个真实的MQTT服务器。 首先,让我们了解一下Vert.x。Vert.x是一个用于构建反应式应用的Java平台,它提供了一种事件驱动、非阻塞I/O模型,使得开发者可以高效地...
vert.x 是一个开源的、高性能的事件驱动应用框架,用于构建反应式的Java应用程序。它以其轻量级、非阻塞I/O模型而闻名,能够充分利用现代多核处理器的潜力,为开发人员提供了一种高效且灵活的方式来构建分布式系统。...
Vert.x实战二:TCP通信:https://blog.csdn.net/haoranhaoshi/article/details/89296522 Vert.x实战三:TCP客户端之间以角色通过服务端转接通信:https://mp.csdn.net/postedit/89296606 Vert.x实战四:TCP客户端...
vert.x 是一个轻量级、高性能的Java应用框架,它主要设计用于构建反应式和异步应用程序。在2.1.2版本中,vert.x 提供了一种创新的方式来开发分布式、事件驱动的应用程序,充分利用了Java平台的非阻塞I/O(NIO)能力...
相比之下,Vert.x可以在多个线程中运行,使得它在处理多核CPU环境下的计算任务时更具优势。 【标签】"Node.Js vertx" 表明这是一个关于比较和使用Node.js与Vert.x的讨论。Node.js以其高效的异步非阻塞I/O和丰富的...
【标题】"Vert.x学习" Vert.x 是一个用于构建反应式应用程序的开源工具包,它在Java生态系统中扮演着重要角色。这个标题暗示了我们将会深入探讨如何利用Vert.x来开发高效、非阻塞和事件驱动的应用程序。Vert.x的...
3. **事件总线(Event Bus)**: Vert.x 的核心特性之一,允许Verticle 之间进行松耦合的通信。事件总线使用发布/订阅模式,允许Verticle 发布消息并被其他感兴趣的Verticle 订阅。 4. **HTTP 服务器**: Vert.x 提供...
标题中的“基于Vert.x(java)开发的API网关”指的是使用Vert.x框架构建的应用程序,该应用程序主要功能是作为API网关。API网关是一种架构模式,它充当客户端(如Web应用、移动应用或IoT设备)与后端服务之间的单一...
- **Vert.x**:虽然Netty也是Vert.x的基础之一,但Vert.x在其之上构建了一个更高层次的抽象。Vert.x通过更细粒度的线程池管理机制,更好地支持了Reactive编程模式。例如,通过Event Loop Group来处理非阻塞任务,...
### Vert.x配置项VertxOptions的使用 #### 概述 在使用Vert.x框架开发分布式应用时,为了更好地控制和优化应用性能,开发者通常需要通过`VertxOptions`类来定制化配置Vert.x实例。`VertxOptions`是用于创建`Vertx`...
QCon Shanghai的演讲者Julien Viet,作为Vert.x项目的领军人物,分享了他在实际测试中所学到的经验教训。 首先,文章提到了一个典型的性能测试案例——Round #8,当时一切运行良好,但随着时间推移,到了Round #14...
Eclipse Vert.x 是一个开源的工具包,专为构建高性能、反应式的Java应用程序而设计。它在互联网领域中被广泛采用,特别是在需要处理高并发、低延迟和分布式系统的情况下。这个框架提供了一种轻量级的方式,使得...
- **Verticle 概念:** Verticle 是 Vert.x 中的核心概念之一,它是一个简单的单元,可以将其理解为服务的最小单元。每个 Verticle 可以独立部署并拥有自己的生命周期。 - **服务发现:** 在分布式环境中,服务发现...
《Vert.x应用开发实例教程》旨在为Vert.x的初学者和大中专院校学生提供易于入门,全面了解和掌握Vert.x框架技术和应用的教材和辅导资料,为使用Vert.x开发实时应用和企业级应用打下良好的基础。
vert.x是内存占用极小的快速开发框架,springboot模版项目
#### 二、什么是Vert.x? Vert.x是一个基于事件驱动模型的轻量级框架,支持多种语言(如Java、Groovy等),其核心特性包括: - **高性能与可伸缩性**:能够高效处理高并发请求。 - **异步编程模型**:通过非阻塞I/O...
Java API 版本的Vert.x Core 手册是关于Vert.x框架的重要参考资料,该框架是用Java编写的高度可扩展的事件驱动平台,适用于构建现代的、反应式的微服务和网络应用。 Vert.x Core是其核心组件,提供了低级别的API,...