<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-json-schema</artifactId>
<version>5.1.10</version>
</dependency>
Vert.x JSON Schema 校验引擎 (vertx-json-schema)
Vert.x JSON Schema 为 JSON Schema 规范提供了可扩展的响应式异步实现。 你可以使用 JSON Schema 校验任意 JSON 数据结构。本模块主要特性包括:
-
支持 Draft 2020-12 规范
-
支持 Draft 2019-09 规范
-
支持 Draft 7 规范
-
支持 Draft 4 规范
-
$ref跨 Schema 外部引用解析(Dereferencing)与缓存加速 -
用于通过纯 Java 代码流式构建 Schema 的类型安全 DSL
引入依赖
要在项目中使用 Vert.x JSON Schema,请在构建描述文件中添加以下依赖:
-
Maven(在
pom.xml中):
-
Gradle(在
build.gradle文件中):
dependencies {
compile 'io.vertx:vertx-json-schema:5.1.10'
}
核心概念
1. JsonSchema
Schema 声明可以呈现为两种形态:
-
标准 JSON 对象形态
-
布尔值形态(如
true / false)
JsonSchema 接口对这两种形态提供了统一封装抽象,使上层调用无须反复分支判断底层形态。
2. SchemaRepository
SchemaRepository 负责管理并维护 JsonSchema 实例集合。它预先对 Schema 进行引用解引(Dereference)以大幅提升后续校验性能。该仓库本质是一个键值存储,不允许存在重复的 Schema ID。
仓库可随后创建感知仓库内全部子 Schema 的 Validator 校验器实例。
3. Validator
Validator 校验器基于给定的根 Schema 对输入 JSON 对象执行结构校验。输出报告的详细度可通过配置自由定制。
解析与加载 Schema
在涉及多个复杂 Schema 或嵌套子 Schema 时,推荐统一使用 Repository:
解析 Schema 首先需要实例化 JsonSchema 并完成基础配置。由于 Schema 内部可能包含 $ref 相对引用,校验器与仓库需要明确应用的 baseUri,以便在子 Schema 间解析跨文件引用。仅进行引用解引时无须预先绑定草案版本:
SchemaRepository repository =
SchemaRepository.create(new JsonSchemaOptions().setBaseUri("https://vertx.io"));
你可以复用 JsonSchema 实例构建不同的 Validator,也可以通过 JsonParser 流式解析 Schema:
JsonSchema schema = JsonSchema.of(object);
// 或者通过仓库执行引用解引并注册:
repository.dereference(JsonSchema.of(object));
|
出于运行时安全性考虑,本模块绝不会在校验阶段尝试通过网络自动下载外部 |
执行数据校验
鉴于 JSON Schema 语法的动态特性以及 if-then-else 等高级条件判定,在流式场景下无法完全实现单遍非阻塞校验。因此校验在底层是一个同步阻塞计算操作。若预料校验过程计算密集且耗时较长,建议在专属 Worker 线程池中执行或使用 executeBlocking 封装。
要校验 Schema:
OutputUnit result = Validator.create(
schema,
new JsonSchemaOptions().setDraft(Draft.DRAFT7))
.validate(json);
if (result.getValid()) {
// 校验成功!数据符合规范
} else {
System.out.println("校验失败,错误原因: " + result.getError() + ",错误类型: " + result.getErrorType());
}
若校验失败,你可以通过 OutputErrorType 排查深层诱因。
通过 Java 代码与 DSL 动态构建 Schema
若希望直接用 Java 代码动态声明 Schema,可以使用内置的 DSL。该功能当前支持 Draft-7 规范。
创建基础类型 Schema
在 Schemas 中提供了各类基础类型的静态构建器:
SchemaBuilder intSchemaBuilder = intSchema();
SchemaBuilder objectSchemaBuilder = objectSchema();
追加关键字约束
你可以通过 Keywords 提供的静态方法为不同类型的 Schema 附加约束条件:
stringSchema()
.with(format(StringFormat.DATETIME));
arraySchema()
.with(maxItems(10));
schema() // 同时接受数组或整型的通用 Schema
.with(type(SchemaType.ARRAY, SchemaType.INTEGER));
组织复合数据结构
创建带有特定属性与附加属性约束的对象 Schema:
objectSchema()
.requiredProperty("name", stringSchema())
.requiredProperty("age", intSchema())
.additionalProperties(stringSchema());
创建数组元素 Schema:
arraySchema()
.items(stringSchema());
创建元组(Tuple)位置约束 Schema:
tupleSchema()
.item(stringSchema()) // 第 1 个元素必须为字符串
.item(intSchema()) // 第 2 个元素必须为整型
.item(booleanSchema()); // 第 3 个元素必须为布尔值
$ref 引用与别名 (Aliases)
通过 Schemas.ref 引入 $ref 引用;使用 id 方法为当前 Schema 赋予 $id 标识。
你还可以为 DSL 构建的 Schema 定义别名(Alias),并借助 Schemas.refToAlias 在其它位置轻松复用:
intSchema()
.alias("myInt");
objectSchema()
.requiredProperty("anInteger", refToAlias("myInt"));
导出 JSON 结构
定义完成后,调用 toJson 即可将其转换为规范的 JSON Schema 对象:
JsonObject schema = objectSchema()
.requiredProperty("name", stringSchema())
.requiredProperty("age", intSchema())
.additionalProperties(stringSchema())
.toJson();