1. 概述

JSON Schema 是一种用于验证JSON 对象格式和结构的声明性语言。它允许我们指定特殊的关键词数量,精确地描述一个有效的JSON 对象应该是什么样子。

JSON Schema 规范分为三部分:

  • JSON Schema 核心:JSON Schema 核心规范定义了 schema 的术语。
  • JSON Schema 验证:JSON Schema 验证规范定义了定义验证约束的有效方式。这份文档还定义了一组可以用于指定 JSON API 验证的关键词。在接下来的例子中,我们将使用其中的一些关键词。
  • JSON 超媒体规范:这是 JSON Schema 规范的另一个扩展,其中定义了与超链接和超媒体相关的关键词。

2. 定义 JSON Schema

现在我们已经定义了 JSON Schema 的用途,让我们创建一个 JSON 对象,并为其编写相应的描述性 JSON Schema。

以下是一个简单的代表产品目录的 JSON 对象:

{
    "id": 1,
    "name": "Lampshade",
    "price": 0
}

我们可以将其 JSON Schema 定义如下:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from the catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

可以看到,JSON Schema 是一个 JSON 文档,且该文档必须是一个对象。由 JSON Schema 定义的对象成员(或属性)称为关键词

让我们解释我们在示例中使用的关键词:

  • $schema 关键词表示这个 schema 是根据draft v4 规范编写的。
  • titledescription 关键词只是描述性的,它们不会增加被验证数据的约束。通过这两个关键词表达了 schema 的意图:描述一个产品。
  • type 关键词定义了对我们的 JSON 数据的第一个约束:它必须是一个 JSON 对象

此外,JSON Schema 可能包含非 schema 关键字的属性。在我们的例子中,idnameprice 将是 JSON 对象的成员(或属性)。

对于每个属性,我们可以定义 type。我们定义了 idnamestringpricenumber。在 JSON Schema 中,数字可以有最小值。默认情况下,最小值是包括在内的,因此我们需要指定 exclusiveMinimum

最后,Schema 告诉我们 idnameprice必需的

3. 使用 JSON Schema 进行验证

有了我们的 JSON Schema,我们可以验证我们的 JSON 对象。

有许多可以完成这项任务。对于我们的示例,我们选择了 Java 的 json-schema 库。

首先,我们需要在 pom.xml 中添加以下依赖:

<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>1.0.72</version>
</dependency>

最后,我们可以编写一些简单的测试用例来验证我们的 JSON 对象:

@Test
public void givenInvalidInput_whenValidating_thenInvalid() throws IOException {
    JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4);
    JsonSchema jsonSchema = factory.getSchema(
     JSONSchemaUnitTest.class.getResourceAsStream("/schema.json"));
    JsonNode jsonNode = mapper.readTree(
     JSONSchemaUnitTest.class.getResourceAsStream("/product_invalid.json"));
    Set<ValidationMessage> errors = jsonSchema.validate(jsonNode);
    assertThat(errors).isNotEmpty().asString().contains("price: must have a minimum value of 0");
}

在这种情况下,将收到验证错误。

第二个测试看起来如下:

@Test 
public void givenValidInput_whenValidating_thenValid() throws ValidationException { 
    JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); 
    JsonSchema jsonSchema = factory.getSchema( 
     JSONSchemaUnitTest.class.getResourceAsStream("/schema.json")); 
    JsonNode jsonNode = mapper.readTree( 
     JSONSchemaUnitTest.class.getResourceAsStream("/product_valid.json")); 
    Set<ValidationMessage> errors = jsonSchema.validate(jsonNode); 
    assertThat(errors).isEmpty(); 
}

由于我们使用了一个有效的 JSON 对象,所以不会抛出验证错误。

4. 总结

在这篇文章中,我们定义了什么是 JSON Schema,以及一些相关的关键字,这些关键字帮助我们定义 schema。

将 JSON Schema 与对应的 JSON 对象结合,我们可以执行一些验证任务。本文的一个简单示例可以在 GitHub 项目中找到。


« 上一篇: Spring Data Neo4j介绍