一、目的
在Web Service对外交互办法的演化中,RESTful API已经成为主流的设计风格,JSON的轻量且简洁优点,使得JSON成为RESTful API紧张的数据交流格式。RESTful要求过程是,客户端发送RESTful要求到Web Service节点,要求header中设置Content-Type=application/json,要求body中是JSON数据,Web Service根据Content-Type校验JSON数据。JSON数据校验有两种策略:一种是在进行实际业务处理前校验,该办法将数据校验和业务处理耦合在一起,可能存在前面数据校验和业务处理成功,后面数据校验失落败,导致前面业务回退,效率低下;另一种是将数据校验和业务处理分开,提前设定JSON数据的Schema,所有业务处理前,JSON数据进行Schema校验,该办法简洁且效率高,已经成为主流办法。
本文先容JSON Schema语法、样例、以及Python和Java中Validation方法,为大家供应参考。

二、语法
2.1 Json Schema Keywords
序号
keyword
是否必须
解释
1
$schema
否
当前文档是否为标准JSON Schema文档,例如:
\"大众$schema\"大众: \"大众http://json-schema.org/draft-04/schema#\"大众
2
$ref
否
引用其他的JSON Schema
3
id
否
id
4
title
否
标题
5
description
否
描述
6
type
是
类型,例如:object、array、string、number、integer、boolean、null、any
7
properties
-
type=object时,properties必须存在
8
patternProperties
否
正则属性,例如:
\"大众patternProperties\"大众: {
\"大众^test_\公众: { \"大众type\"大众: \"大众string\"大众 },
}
test开头且类型为string的属性
9
additionalProperties
否
false - JSON串中只能涌现Schema中定义的属性
true - JSON串中可以涌现不在Schema中定义的属性
\"大众additionalProperties\"大众: { \公众type\公众: \"大众string\"大众 } - JSON串中可以涌现不在Schema中定义的属性,但类型必须string
10
required
否
必须涌现的properties
11
dependencies
否
12
size
否
13
minimum
否
type=number,最小值
14
exclusiveMinimum
否
type=number,最小值,不包含minimum
15
maximum
否
type=number,最大值
16
exclusiveMaximum
否
type=number,最大值,不包含maximum
17
multipleOf
否
18
anyOf
否
知足任意一个即可,例如:
{
\"大众anyOf\"大众: [
{ \"大众type\"大众: \"大众string\"大众},
{ \"大众type\"大众: \"大众number\"大众}
]
}
19
allOf
否
知足所有,例如:
{
\公众allOf\公众: [
{ \公众type\"大众: \"大众string\"大众 },
{ \"大众maxLength\公众: 5 }
]
}
20
oneOf
否
知足唯一一个,例如:
{
\公众type\"大众: \"大众string\"大众,
\"大众oneOf\公众: [
{ \"大众format\"大众: \"大众host-name\"大众 },
{ \公众format\"大众: \"大众ipv4\"大众 },
{ \公众format\"大众: \公众ipv6\公众 }
]
}
21
not
否
例如:
{
\"大众not\"大众: {
\"大众type\公众: \"大众string\"大众
}
}
22
items
-
type=array时,items必须存在
23
enum
否
列举类型,例如:
{
\"大众type\公众: \公众string\公众,
\公众enum\公众: [\"大众test1\"大众, \"大众test2\"大众, \公众test3\公众]
}
属性类型为string,且只能是test1、test2、test3个中一个。
24
minItems
否
type=array,最小条款个数
25
maxItems
否
type=array,最大条款个数
26
uniqueItems
否
type=array,true - 条款不重复,反之可重复
27
minLength
否
type=string,最小字符个数
28
maxLength
否
type=string,最大字符个数
29
format
否
format规则,优先级大于type,包括:date-time、date、time、utc-millisec、regex、color、style、phone、uri、email、ip-address、ipv6、host-name、uuid、anything else(type unchanged)
30
divisibleBy
否
31
disallow
否
不包含,例如:
{
\"大众type\"大众: \公众object\"大众,
\公众properties\公众: {
\"大众id\"大众: {
\公众disallow\"大众: \"大众any\公众
},
\"大众name\"大众: {
\"大众type\"大众: \公众string\公众,
\"大众required\"大众: true
}
}
}
32
extends
否
继续,例如:
{
\"大众type\"大众 : \公众object\公众,
\"大众extends\公众 : {
\公众$ref\"大众 : \"大众xxx.json\"大众
}
}
33
default
否
默认值
34
definitions
否
复用Json Schema,例如:
{ \公众$ref\公众: \"大众#/definitions/xxx\公众 }
{ \"大众$ref\"大众: \"大众definitions.json#/xxx\公众 }
35
pattern
否
正则值,例如:
{
\"大众type\"大众: \公众string\公众,
\"大众pattern\公众: \"大众^test\"大众
}
test开头的值
2.2 Json Schema Example
Json Schema
{
\公众$schema\公众: \"大众http://json-schema.org/draft-04/schema#\"大众,
\"大众title\公众: \"大众Test\公众,
\"大众type\"大众: \"大众array\公众,
\公众items\公众: {
\"大众type\公众: \"大众object\公众,
\"大众properties\"大众: {
\"大众prop1\"大众: {
\公众description\公众: \公众prop1\公众,
\"大众type\"大众: \公众integer\"大众
},
\"大众prop2\"大众: {
\公众description\公众: \公众prop2\"大众,
\"大众type\"大众: \"大众string\公众,
\"大众enum\"大众: [\"大众test1\"大众, \"大众test2\公众, \公众test3\公众]
},
\"大众prop3\"大众: {
\公众type\公众: \公众number\"大众,
\公众minimum\公众: 60,
\公众exclusiveMinimum\公众: true,
\"大众maximum\"大众: 100,
\"大众exclusiveMaximum\"大众: true
}
},
\"大众required\"大众: [\公众prop1\"大众, \"大众prop2\"大众, \"大众prop3\"大众]
},
minItems: 1,
maxItems: 5,
uniqueItems: true
}
Json Instance
[{
'prop1': 1,
'prop2': 'test1',
'prop3': 91
},
{
'prop1': 2,
'prop2': 'test2',
'prop3': 92
}
]
三、运用
3.1 Python Json Schema Validation
# JSON_SCHEMA:json schema string
# JSON_INSTANCE: json instance string
from jsonschema.validators import Draft4Validator
validator = Draft4Validator(schema=JSON_SCHEMA)
validator.validate(JSON_INSTANCE)
3.2 Java Json Schema Validation
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
JsonNode schemaNode = JsonLoader.fromString(JSON_SCHEMA);
JsonNode instanceNode = JsonLoader.fromString(JSON_INSTANCE);
JsonSchema jsonSchema = factory.getJsonSchema(schemaNode);
ProcessingReport report = jsonSchema.validate(instanceNode);
四、参考
[1] The JSON Schema web site:
http://www.json-schema.org
[2] The JSON Schema github:
https://github.com/json-schema-org
[3] JSON instance to JSON schema:
https://jsonschema.net/#/
[4] JSON Schema instance validation:
https://www.jsonschemavalidator.net/