Vert.x - Web Validation 请求校验

Posted 小毕超

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vert.x - Web Validation 请求校验相关的知识,希望对你有一定的参考价值。

一、Web Validation

上篇文章我们学习了 vertx 中使用 thymeleaf、freemarker 模板引擎,本篇文章我们学习下非常常用和实用的 Web Validation 请求校验器,Web Validation 可以用来对照 Spring Validation ,在请求到达我们的 handler 之前进行校验合法性,如果不合法会抛出 400 错误信息,因此如果捕获这些错误信息,我们可以通过router.errorHandler 捕获 状态码是 400 的错误,也可以使用 failureHandler 捕获全部异常。

下面是上篇文章的地址:

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

下面一起实践下 Web Validation 的使用。

二、 Web Validation 参数校验

首先需要引入 Web Validation 的依赖,在pom中添加下面依赖:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web-validation</artifactId>
    <version>4.1.8</version>
</dependency>

在进行参数校验前,我们需要创建一个参数解析器,目前 vertx 支持三种模式:

本文我们使用 Draft7S ,创建一个解析器:

SchemaParser parser = SchemaParser.createDraft7SchemaParser(
        SchemaRouter.create(vertx, new SchemaRouterOptions())
);

上面提到如果校验不合法会抛出 400 错误信息,可以通过router.errorHandler 捕获 ,那我们就要声明出一个 errorHandler ,在这里将错误信息返回出去:

router.errorHandler(400, ctx -> 
    ctx.json(new JsonObject().put("code", 400).put("message", ctx.failure().getMessage()));
);

下面就可以开始参数校验了,在 vertx 中有开箱即用的 ValidationHandler ,在业务前先经过 ValidationHandler 进行校验,其中对参数的规范可以通过 Schemas 对象进行,可以规范参数的类型比如,只接收数字类型等,还可以规定参数的大小、长度等。

ValidationHandler 解析后会把解析到的参数放入RequestParameters对象中,这个对象又会放入 RoutingContext 中,其中keyrequestParameters , 因此也可以通过 RoutingContext.get("requestParameters")获取到 RequestParameters 对象,进而获取到参数信息。

有个需要注意的地方,就是在校验 json、formUrlEncoded、formDate 等,这种参数放在请球体中时,需要经过BodyHandler的处理后再交给 ValidationHandler 才可以,不然会解析不到参数,一直校验不通过,可以提前声明好,ValidationHandler 校验后到业务 handler 可以通过 body().getJsonObject()的方式获取参数。

 router.route().handler(BodyHandler.create());

queryParameter 校验

比如接口nameage两个参数,其中name 定义为字符类型, age为 数字类型,并且age的大小在0100 之间:

 router.get("/queryParameter")
         .handler(ValidationHandler.builder(parser)
                 .queryParameter(param("name", Schemas.stringSchema()))
                 .queryParameter(param("age", Schemas.numberSchema().with(Keywords.maximum(100)).with(Keywords.minimum(0))))
                 .build()
         )
         .handler(ctx -> 
             RequestParameters parameters = ctx.get(ValidationHandler.REQUEST_CONTEXT_KEY);
             String name = parameters.queryParameter("name").getString();
             double age = parameters.queryParameter("age").getDouble();
             System.out.println(name);
             System.out.println(age);
             ctx.json(new JsonObject().put("code", 200).put("message", "success"));
         );

当没有参数时:

age 为字符时:

age > 100 时:

age 在 0 到 100 之间时:

pathParameter 校验

有时参数是通过 url 地址的方式传递过来的,这种也是可以通过 ValidationHandler 进行校验:

router.get("/pathParameter/:num")
      .handler(ValidationHandler.builder(parser)
              .pathParameter(param("num", Schemas.numberSchema().with(Keywords.maximum(100)).with(Keywords.minimum(0))))
              .build()
      )
      .handler(ctx -> 
          RequestParameters parameters = ctx.get(ValidationHandler.REQUEST_CONTEXT_KEY);
          double path = parameters.pathParameter("path").getDouble();
          System.out.println(path);
          ctx.json(new JsonObject().put("code", 200).put("message", "success"));
      );

formUrlEncoded 校验

由于这种方式参数是放在 请求体中的,所以进行校验也需要到 body 下进行:

router.post("/formUrlEncoded")
      .handler(ValidationHandler.builder(parser)
              .body(Bodies.formUrlEncoded(objectSchema()
                      .property("username", Schemas.stringSchema().with(Keywords.minLength(5)))))
              .build()
      )
      .handler((ctx -> 
          RequestParameters params = ctx.get("parsedParameters");
          JsonObject body = params.body().getJsonObject();
          System.out.println(body.toString());
          ctx.json(new JsonObject().put("code", 200).put("message", "success"));
      ));

multipartFormData 校验

multipartFormData 和上面的 formUrlEncoded 一样参数都是放在请求体的:

router.post("/multipartFormData")
        .handler(ValidationHandler.builder(parser)
                .body(Bodies.multipartFormData(objectSchema()
                        .property("username", Schemas.stringSchema().with(Keywords.minLength(5)))))
                .build()
        )
        .handler((ctx -> 
            RequestParameters params = ctx.get("parsedParameters");
            JsonObject body = params.body().getJsonObject();
            System.out.println(body.toString());
            ctx.json(new JsonObject().put("code", 200).put("message", "success"));
        ));

JSON 校验

校验 JSON 参数也是上同,都在请求体中:

router.post("/json")
        .handler(ValidationHandler.builder(parser)
                .body(Bodies.json(objectSchema()
                        .property("username", Schemas.stringSchema().with(Keywords.minLength(5)))))
                .build()
        )
        .handler((ctx -> 
            RequestParameters params = ctx.get("parsedParameters");
            JsonObject body = params.body().getJsonObject();
            System.out.println(body.toString());
            ctx.json(new JsonObject().put("code", 200).put("message", "success"));
        ));

以上是关于Vert.x - Web Validation 请求校验的主要内容,如果未能解决你的问题,请参考以下文章

Vert.x-Web的讲解和使用

Vert.x-Web的讲解和使用

如何使用 Vert.x 实现非阻塞 REST Web 服务

Vert.x Web之Router

Vert.x Java开发指南 第一章 介绍

Vert.x学习之 Web Client