该库目前处于维护模式,已被 erosb/json-sKema 取代。
这个仓库不会有任何新功能。它为 JSON Schema 规范的 draft-04、draft-06 和 draft-07 版本提供了稳固的支持。
最新的 draft 2020-12 版本仅由 erosb/json-sKema 支持。
[![Apache 2.0 许可证][ASL 2.0 badge]][ASL 2.0] [![构建状态][Travis badge master]][Travis] [![覆盖率状态][Coveralls.io badge master]][Coveralls.io]
这个项目是 JSON Schema [Draft v4][draft-zyp-json-schema-04]、Draft v6 和 Draft v7 规范的实现。 它使用 org.json API(由 Douglas Crockford 创建)来表示 JSON 数据。
假设你已经知道什么是 JSON Schema,并且想在 Java 应用程序中使用它来验证 JSON 数据。 但是 - 你可能已经发现 - 还有[另一个 Java 实现][java-json-tools/json-schema-validator]的 JSON Schema 规范。以下是一些关于选择哪一个的建议:
在你的 pom.xml
中添加以下依赖:
<dependency> <groupId>com.github.erosb</groupId> <artifactId>everit-json-schema</artifactId> <version>1.14.4</version> </dependency>
关于旧版本的注意事项:版本 1.6.0
到 1.9.1
之间只能在 JitPack 上找到,坐标为 com.github.everit-org.json-schema:org.everit.json.schema
。版本 1.0.0
... 1.5.1
在 Maven Central 上可用,坐标为 org.everit.json:org.everit.json.schema
。
有几次尝试使这个库在 Java 6/7 上工作。
@mindbender1 开发了 1.9.2 版本的 java6 移植版,可以通过 Maven Central 使用以下坐标访问:
<dependency> <groupId>com.github.erosb</groupId> <artifactId>everit-json-schema-jdk6</artifactId> <version>1.9.2</version> </dependency>
旧版本的向后移植:
com.doctusoft:json-schema-java7:1.4.1
com.github.rdruilhe.json-schema:org.everit.json.schema:1.1.1
import org.everit.json.schema.Schema; import org.everit.json.schema.loader.SchemaLoader; import org.json.JSONObject; import org.json.JSONTokener; // ... try (InputStream inputStream = getClass().getResourceAsStream("/path/to/your/schema.json")) { JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream)); Schema schema = SchemaLoader.load(rawSchema); schema.validate(new JSONObject("{\"hello\" : \"world\"}")); // 如果这个对象无效,则抛出 ValidationException }
JSON Schema 目前有 4 个主要版本,Draft 3、Draft 4、Draft 6 和 Draft 7。这个库实现了其中的 3 个较新版本,你可以在这里和这里快速了解它们之间的差异。 由于两个版本有许多差异 - 而且 draft 6 不向后兼容 draft 4 - 知道你将使用哪个版本是很好的。 指定要使用的JSON Schema版本的最佳方法是在文档根节点使用"$schema"键包含其元模式URL。这是一种常见的表示法,便于库确定应使用哪个版本。
快速参考:
"$schema": "http://json-schema.org/draft-04/schema"
,则使用Draft 4"$schema": "http://json-schema.org/draft-06/schema"
,则使用Draft 6"$schema": "http://json-schema.org/draft-07/schema"
,则使用Draft 7如果你想明确指定元模式版本,可以通过如下方式配置加载器,将默认版本从Draft 4更改为Draft 6/7:
SchemaLoader loader = SchemaLoader.builder() .schemaJson(yourSchemaJSON) .draftV6Support() // 或 draftV7Support() .build(); Schema schema = loader.load().build();
从1.1.0 版本开始,验证器会收集所有模式违规(而不是在第一个违规处立即失败)。每个失败都用JSON指针表示,从文档根指向违规部分。如果检测到多个模式违规,则会在违规的最近公共父元素处抛出ValidationException
,可以使用ValidationException#getCausingExceptions()
方法获取每个单独的违规。
为了演示上述概念,让我们看一个例子。考虑以下模式:
{ "type" : "object", "properties" : { "rectangle" : {"$ref" : "#/definitions/Rectangle" } }, "definitions" : { "size" : { "type" : "number", "minimum" : 0 }, "Rectangle" : { "type" : "object", "properties" : { "a" : {"$ref" : "#/definitions/size"}, "b" : {"$ref" : "#/definitions/size"} } } } }
以下JSON文档对该模式只有一处违规(因为"a"不能为负):
{ "rectangle" : { "a" : -5, "b" : 5 } }
在这种情况下,抛出的ValidationException
将指向#/rectangle/a
,并且不包含子异常:
try { schema.validate(rectangleSingleFailure); } catch (ValidationException e) { // 打印 #/rectangle/a: -5.0 is not higher or equal to 0 System.out.println(e.getMessage()); }
现在,为了说明如何处理多个违规,让我们考虑以下JSON文档,其中"a"和"b"属性都违反了上述模式:
{ "rectangle" : { "a" : -5, "b" : "asd" } }
在这种情况下,抛出的ValidationException
将指向#/rectangle
,并且有2个子异常,分别指向#/rectangle/a
和#/rectangle/b
:
try { schema.validate(rectangleMultipleFailures); } catch (ValidationException e) { System.out.println(e.getMessage()); e.getCausingExceptions().stream() .map(ValidationException::getMessage) .forEach(System.out::println); }
这将打印以下输出:
#/rectangle: 2 schema violations found
#/rectangle/a: -5.0 is not higher or equal to 0
#/rectangle/b: expected type: Number, found: String
从1.4.0版本开始,可以将ValidationException
实例打印为JSON格式的失败报告。ValidationException#toJSON()
方法返回一个JSONObject
实例,包含以下键:
"message"
: 对程序员友好的异常消息(验证失败的描述)"keyword"
: 违反的JSON Schema关键字"pointerToViolation"
: 一个JSON指针,表示从输入文档根到导致验证失败的片段的路径"schemaLocation"
: 一个JSON指针,表示从模式JSON根到违反的关键字的路径"causingExceptions"
: 一个(可能为空的)子异常数组。每个子异常都表示为一个JSON对象,结构与本列表中描述的相同。有关导致异常的更多信息,请参见上文。请注意,完整的失败报告是一个层次树结构:可以使用#getCausingExceptions()
获取一个原因的子原因。
ValidationListener
可以用于解决实例JSON如何匹配(或不匹配)模式的歧义。你可以将ValidationListener
实现附加到验证器,以接收有关中间成功/失败结果的事件通知。
示例:
import org.everit.json.schema.Validator; ... Validator validator = Validator.builder() .withListener(new YourValidationListenerImplementation()) .build(); validator.performValidation(schema, input);
当前支持的事件:
"$ref"
引用"allOf"
/ "anyOf"
/ "oneOf"
模式下的子模式匹配"allOf"
/ "anyOf"
/ "oneOf"
模式下的子模式匹配失败"if"
模式匹配"if"
模式匹配失败"then"
模式匹配"then"
模式匹配失败"else"
模式匹配"else"
模式匹配失败