首页 > 编程学习 > Vert.x - vertx-web 路由讲解总结

Vert.x - vertx-web 路由讲解总结

发布时间:2022/11/24 23:23:11

在这里插入图片描述

一、vertx-web

上篇文章我们对 vertx 进行了简单的介绍,并使用 vertx-web 实践了 restFul 接口的书写,本篇文章接着上篇继续讲解 vertx-web 的路由。

下面是上篇文章的地址:

https://blog.csdn.net/qq_43692950/article/details/123955368

对于环境的搭建请参考上篇文章的内容。

二、vertx-web 路由

1. 精确匹配

精确路径是日常开发中常用的方式,精确匹配到某个接口。

router.get("/test1").handler(ctx -> {ctx.response().end("success");
});

在这里插入图片描述

2. 路径前缀的匹配

有的时候可能需要匹配以某某为开头的请求,此时可以使用路径前缀的路由,在vertx 中可以使用 * 代表路径,如:

router.get("/test/*").handler(ctx -> {String url = ctx.request().absoluteURI();ctx.response().end(url+"--> success");
});

在这里插入图片描述
还可以通过这种方式还可以对接口进行拦截或处理:

router.get("/test/*").handler(ctx -> {String url = ctx.request().absoluteURI();if (Objects.isNull(ctx.request().getParam("p"))){ctx.response().end("参数为空!");return;}ctx.next();
});
router.get("/test/abc").handler(ctx -> {String url = ctx.request().absoluteURI();ctx.response().end(url+"--> success2");
});

上面以/test开头的必须要携带 p 参数:
在这里插入图片描述
在这里插入图片描述

3. 获取路径上的参数

SpringMVC 中我们可以通过 @PathVariable 获取路径上的参数,在 vertx 中同样也是可以的,可以使用 :参数名 的方式,如:

router.get("/pathParam/:name/:age").handler(ctx -> {String name = ctx.pathParam("name");String age = ctx.pathParam("age");ctx.response().end(name+"  "+age);
});

在这里插入图片描述

4. 使用正则表达式进行匹配

前面有使用 * 的方式来匹配任意后缀的请求,但使用正则的话可以满足基本任何规则的匹配,在 vertx 正则的方法都带有WithRegex
在这里插入图片描述
基本上常用的请求方式都支持正则,如匹配abc结尾的后缀:

router.getWithRegex(".*abc").handler(ctx->{String url = ctx.request().absoluteURI();ctx.response().end(url + "--> success");
});

在这里插入图片描述

5. 路由顺序

上面路径前缀的匹配说到可以利用这个进行请求的拦截,其实就是使用的 vertx 中的路由顺序,在 vertx 中,声明同一个 url 不会进行覆盖而是都会加载到该 url 请求的列表中,默认进入第一个请求,可以通过 ctx.next() 执行下一个,如:

router.get("/shunxu").handler(ctx -> {if (Objects.isNull(ctx.request().getParam("p"))) {ctx.response().end("没有传递参数!");} else {ctx.next();}
});
router.get("/shunxu").handler(ctx -> {ctx.response().end("参数: " + ctx.request().getParam("p"));
});

在这里插入图片描述
在这里插入图片描述

6. 限制请求的MIME类型

有时候我们的接口可能只想接收 Content-Type=application/json的请求,其他的都不接收,可以通过 consumes 进行限制,并且在 vertx 中还提供了ctx.is 可以用来判断请求的类型是否属于某一类:如:

router.get("/mime").consumes("application/json").handler(ctx -> {String header = ctx.request().getHeader("Content-Type");boolean b = ctx.is("application/json");boolean b1 = ctx.is("application/json;charset=UTF-8");boolean b2 = ctx.is("text/json");ctx.response().putHeader("Content-Type","text/html").end(header + " , " + b + " , " + b1 + " , " + b2);});

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看出限制是包含关系。

7. VirtualHost 限制

有些情况我们的接口可能只允许某个 host 的请求,此时就可以使用 VirtualHost ,如限制为127.0.0.1 则使用 localhost 则访问不同 :

router.get("/virtualHost").virtualHost("127.0.0.1").handler(ctx->{String url = ctx.request().absoluteURI();ctx.response().end(url + "--> success");
});

在这里插入图片描述
在这里插入图片描述

8. 上下文数据传递

在上面说请求顺序的时候,涉及到多个 请求handler , 而多个 handler 之间也是可以传递数据的,可以通过 ctx.put 进行:

router.get("/put").handler(ctx->{String p = ctx.request().getParam("p");ctx.put("p",p+"123");ctx.next();
}).handler(ctx->{Optional.ofNullable(ctx.get("p")).map(String::valueOf).ifPresent(p->{ctx.response().end(p);});
});

在这里插入图片描述

9. 重定向

在vertx 中直接使用 ctx.redirect 即可实现重定向,如:重定向到百度:

router.get("/redirect").handler(ctx -> {ctx.redirect("http://www.baidu.com");
});

在这里插入图片描述

重定向到内部其他接口:

router.get("/redirect").handler(ctx -> {ctx.redirect("/test");
});

10. 返回JSON

vertx 中返回 json ,可以直接使用提供的 ctx.json 即可,传入一个 JsonObject

router.get("/getJson").handler(ctx -> {JsonObject jsonObject = new JsonObject().put("code", "200").put("message", "success");ctx.json(jsonObject);
});

在这里插入图片描述

11. 失败处理

在逻辑执行时,如果遇到异常此时没有捕获的话就会返回 500 ,对此 vertx 提供了 failureHandler ,来捕获异常,有点类似于服务的降级,failureHandler 可以全局捕获也可以针对某个请求:

router.get("/err").handler(ctx -> {int a = 1 / 0;
}).failureHandler(ctx -> {ctx.response().end("请求异常:" + ctx.failure().getMessage());
});

在这里插入图片描述
全局捕获:

router.route().failureHandler(ctx->{ctx.response().end("请求异常:" + ctx.failure().getMessage());
});router.get("/err").handler(ctx -> {int a = 1 / 0;
});

12. 文件上传

vertx 的文件上传已经帮我们做了简化,直接使用BodyHandler进行处理即可,文件默认放在当前的 file-uploads 下,并且为了防止重名,存在该目录下的并不是我们上传的文件名,而是 UUID,到我们自己的 handler 中只需使用 ctx.fileUploads 即可获取到上传的文件信息。

注意点:本篇文章采用的 vertx 版本为 4.1.8 ,如果整合 SpringBoot ,需要使用 2.2.X的版本,如果是 2.3.X 上传文件会卡住,解决办法是使用 vertx 4.2.x 的版本在 SpringBoot 2.3.X 是正常的。

router.post("/fileupload").handler(BodyHandler.create().setHandleFileUploads(true).setBodyLimit(5*1024*1024).setPreallocateBodyBuffer(true)).handler(ctx -> {Set<FileUpload> set = ctx.fileUploads();System.out.println("上传文件数:"+set.size());if (set.isEmpty()) {ctx.response().end("文件为空!");return;}set.forEach(f -> {System.out.println("name: "+f.name());System.out.println("fileName: "+f.fileName());System.out.println("uploadedFileName: "+f.uploadedFileName());});ctx.response().end("success");});

在这里插入图片描述
在这里插入图片描述
下面是上传到服务的文件:
在这里插入图片描述

13. 静态资源

Vertx 带有开箱即用的 StaticHandler 实例处理静态资源,用于处理静态Web资源,默认静态文件目录为 webroot。

router.route("/static/*").handler(StaticHandler.create());

在这里插入图片描述
在这里插入图片描述

14. 允许跨域

Vertx 中跨域也有开箱即用的 CorsHandler,首先写一个普通接口:

router.get("/cors").handler(ctx -> {ctx.response().end("success");
});

使用 ajax 调用上面的接口:

$.ajax({url: "http://localhost:8090/cors",type: "get",success: function (result) {console.log(result)}
});

浏览器请求:
在这里插入图片描述
出现了跨域的错误,下面添加跨域的允许:

router.route().handler(CorsHandler.create().addOrigin("*").allowedHeader(" x-www-form-urlencoded, Content-Type,x-requested-with").allowedMethod(HttpMethod.GET).allowedMethod(HttpMethod.POST).allowedMethod(HttpMethod.PUT).allowedMethod(HttpMethod.DELETE));

再次刷新页面:
在这里插入图片描述
在这里插入图片描述
喜欢的小伙伴可以关注我的个人微信公众号,获取更多学习资料!


本文链接:https://www.ngui.cc/zz/1443307.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000