`
zzqfsy
  • 浏览: 3854 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Vert.x之旅(二):Route

 
阅读更多

一个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.

限制大小:

setBodyLimit

过大则413 -Request Entity Too Large

表单属性合并

setMergeFormAttributes.

文件上传:

router.route().handler(BodyHandler.create());
 
router.post("/some/path/uploads").handler(routingContext ->{
 
 Set<FileUpload> uploads = routingContext.fileUploads();
 // Do something with uploads....
 
});

 

支持cookies处理

使用CookieHandler.

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 4 核心手册中文版】深入解析 Vert.x 是一个轻量级、高性能的反应式应用开发框架,适用于 Java 和其他多种语言。它的核心组件小巧且灵活,允许开发者只使用需要的部分,并能无缝嵌入到现有的应用程序中,...

    Vert.x应用开发实例教程

    Vert.x是事件驱动的,其处理请求的高性能也是基于其事件机制。Vert.x的事件机制中有几个非常重要的概念:Event Loop、Event Loop Vertical、Worker Vertical、Event Bus、Vert.x Module。 Event Loop:即事件循环,...

    vert.x中文 PDF 下载

    vert.x 是一个开源的、高性能的事件驱动应用框架,用于构建反应式的Java应用程序。它以其轻量级、非阻塞I/O模型而闻名,能够充分利用现代多核处理器的潜力,为开发人员提供了一种高效且灵活的方式来构建分布式系统。...

    vert.x结合springboot开发mqtt服务,真实可用

    本教程将探讨如何使用Vert.x和Spring Boot结合来开发一个真实的MQTT服务器。 首先,让我们了解一下Vert.x。Vert.x是一个用于构建反应式应用的Java平台,它提供了一种事件驱动、非阻塞I/O模型,使得开发者可以高效地...

    Vert.x的Http和TCP实战

    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-2.1.2

    vert.x 是一个轻量级、高性能的Java应用框架,它主要设计用于构建反应式和异步应用程序。在2.1.2版本中,vert.x 提供了一种创新的方式来开发分布式、事件驱动的应用程序,充分利用了Java平台的非阻塞I/O(NIO)能力...

    vert.x 3.3.3

    相比之下,Vert.x可以在多个线程中运行,使得它在处理多核CPU环境下的计算任务时更具优势。 【标签】"Node.Js vertx" 表明这是一个关于比较和使用Node.js与Vert.x的讨论。Node.js以其高效的异步非阻塞I/O和丰富的...

    Vert.x学习

    【标题】"Vert.x学习" Vert.x 是一个用于构建反应式应用程序的开源工具包,它在Java生态系统中扮演着重要角色。这个标题暗示了我们将会深入探讨如何利用Vert.x来开发高效、非阻塞和事件驱动的应用程序。Vert.x的...

    Vert.x 初始demo

    3. **事件总线(Event Bus)**: Vert.x 的核心特性之一,允许Verticle 之间进行松耦合的通信。事件总线使用发布/订阅模式,允许Verticle 发布消息并被其他感兴趣的Verticle 订阅。 4. **HTTP 服务器**: Vert.x 提供...

    基于Vert.x(java)开发的API网关,是一个分布式,全异步,高性能,可扩展,轻.zip

    标题中的“基于Vert.x(java)开发的API网关”指的是使用Vert.x框架构建的应用程序,该应用程序主要功能是作为API网关。API网关是一种架构模式,它充当客户端(如Web应用、移动应用或IoT设备)与后端服务之间的单一...

    Vert.x线程模型揭秘

    - **Vert.x**:虽然Netty也是Vert.x的基础之一,但Vert.x在其之上构建了一个更高层次的抽象。Vert.x通过更细粒度的线程池管理机制,更好地支持了Reactive编程模式。例如,通过Event Loop Group来处理非阻塞任务,...

    Vert.x配置项VertxOptions的使用

    ### Vert.x配置项VertxOptions的使用 #### 概述 在使用Vert.x框架开发分布式应用时,为了更好地控制和优化应用性能,开发者通常需要通过`VertxOptions`类来定制化配置Vert.x实例。`VertxOptions`是用于创建`Vertx`...

    从HTTP性能基准测试谈Vert.x高性能的秘密:从JIT编译到网络优化_英文.pdf

    QCon Shanghai的演讲者Julien Viet,作为Vert.x项目的领军人物,分享了他在实际测试中所学到的经验教训。 首先,文章提到了一个典型的性能测试案例——Round #8,当时一切运行良好,但随着时间推移,到了Round #14...

    使用Eclipse_Vert.x开发响应式应用_英文.pdf

    Eclipse Vert.x 是一个开源的工具包,专为构建高性能、反应式的Java应用程序而设计。它在互联网领域中被广泛采用,特别是在需要处理高并发、低延迟和分布式系统的情况下。这个框架提供了一种轻量级的方式,使得...

    Java vert.x微服务框架资料

    - **Verticle 概念:** Verticle 是 Vert.x 中的核心概念之一,它是一个简单的单元,可以将其理解为服务的最小单元。每个 Verticle 可以独立部署并拥有自己的生命周期。 - **服务发现:** 在分布式环境中,服务发现...

    vertx应用开发实例教程-完整版

     《Vert.x应用开发实例教程》旨在为Vert.x的初学者和大中专院校学生提供易于入门,全面了解和掌握Vert.x框架技术和应用的教材和辅导资料,为使用Vert.x开发实时应用和企业级应用打下良好的基础。

    vert.x-springboot模版项目

    vert.x是内存占用极小的快速开发框架,springboot模版项目

    Vert.x for Java 开发者

    #### 二、什么是Vert.x? Vert.x是一个基于事件驱动模型的轻量级框架,支持多种语言(如Java、Groovy等),其核心特性包括: - **高性能与可伸缩性**:能够高效处理高并发请求。 - **异步编程模型**:通过非阻塞I/O...

    Java API 版本的Vert.x Core 手册等三本书

    Java API 版本的Vert.x Core 手册是关于Vert.x框架的重要参考资料,该框架是用Java编写的高度可扩展的事件驱动平台,适用于构建现代的、反应式的微服务和网络应用。 Vert.x Core是其核心组件,提供了低级别的API,...

Global site tag (gtag.js) - Google Analytics