1:JSON Schema简介
学习json schema基础
和XML Schema用来验证xml数据结构一样,jsonSchema是验证JSONdata数据结构的强大工具。
如果不会写有自动生成工具:https://www.jsonschema.net/login
1.1:基础知识
在JSON模式中,空对象和true都是完全有效的模式,可以接受任何有效的JSON。
- a.json文件
{ } 或者true
1.2:定义关键字解释
架构关键字:$schema and $id.
$schema该关键字用于指定JSON Schema版本信息
Id是唯一标识产品的数值。因为这是产品的规范标识符,所以它是必需的。
模式注释:title and description.
用来进行注释的,描述文件或者字段
验证关键字:type。
定义数据的类型,定义后只支持该特定类型
属性关键字:properties
定义该json的属性部分
demo
{
"id":"this is json id .",
"description":"this is test json schema .",
"properties":{
"name":{
"type":"string",
"description":"people name ."
}
}
}
1:$schema
用于指定版本信息:可在此查看schema版本
共有4;6;7等多个版本,比如6版本
"$schema": "http://json-schema.org/draft-06/schema#",
2:type支持数据类型
string
number
integer
object
array
boolean
null
2.1:string字符串
支持对字符串的长度,正则表达式。对于其他的一些格式,因为json中没有时间,ip等格式,统一为字符串,可以使用format关键字再进行定义。
定义字符串长度范围,值必须是非负数
{
"type": "string",
"minLength": 2,
"maxLength": 3
}
- 支持的参数
长度:minLength,maxLength
正则表达式 :pattern
其他内置格式:对应使用format关键字: "format":"",
日期和时间:date-time;time;date;
邮件地址:email;idn-email
主机名:hostname
IP:ipv4;ipv6
资源标识符:uuid;uri
url模板:uri-template
json指针:JSON Pointer
正则表达式:regex
1:正则表达式
string支持正则表达式介绍。正则表达式规则介绍
.:匹配除换行符以外的任何字符。
^:仅在字符串的开头匹配。
$:仅在字符串末尾匹配。
(...):将一系列正则表达式组合成一个正则表达式。
|:匹配前面或后面的正则表达式|符号。
[abc]:匹配方括号内的任何字符。
[a-z]:匹配字符范围内的所有。
[^abc]:匹配字符以外的。
[^a-z]:匹配范围之外的任何字符。
+:匹配前面正则表达式的一个或多个重复。
*:匹配前面正则表达式的零个或多个重复。
?:匹配前面正则表达式的零个或一个重复。
+?,*?,??:该*,+,和?限定词都是贪婪的;它们匹配尽可能多的文本。有时这种行为是不可取的,您希望匹配尽可能少的字符。
(?!十),(?=x):消极和积极的前瞻。
{x}:完全匹配前面x位数正则表达式的出现。
{x,y}:至少匹配x最多y出现在前面位数的正则表达式。
{x,}:匹配x前面正则表达式的一次或多次出现。
{x}?,{x,y}?,{x,}?:上述表达式的懒惰版本。
demo:
{
"type": "string",
"pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$",
}
//"(888)555-1212" 或者"555-1212" 都是符合的
// ^(([0-9]{3}))? 匹配0-9的数字匹配前3位,执行一次匹配或者0次
// [0-9]{3} 再匹配0-9的数子匹配3位,
// -[0-9]{4}$ -在数据末尾执行匹配0-9的数据匹配4位
2.2:数字类型
JSON模式中有两种数字类型:integer和number。它们共享相同的验证关键字。
- integer:同于整数,不适用于小数点。
- number:用于任何数值类型,整数或浮点数字。
两者均可用于包括大写的一到十。
支持参数
倍数:multipleOf
范围:
x ≥ minimum
x > exclusiveMinimum
x ≤ maximum
x < exclusiveMaximum
2.3:object对象
对象是JSON中的映射类型。它们将“键”映射到“值”。在JSON中,“键”必须总是字符串。每一对通常被称为“property”。
{ “type”: “object” } :一个键值对也可以成为一个对象
object支持可选参数
{
"type": "object",
"properties": {},
"patternProperties":{},
"additionalProperties ":fasle或者true或者额外字段类型的定义,
"required":[],
"minProperties": 1,
"maxProperties": 5
}
- 1:properties
properties 用于描述一个object对象的多个属性
{
"type": "object",
"properties": {
"number": { "type": "number" }
}
}
{ “number”: 1600}
- 2:patternProperties
对符合正则匹配的字段套用该定义
{
"type": "object",
"patternProperties": {
"^S_": { "type": "string" },
"^I_": { "type": "integer" }
}
}
{ “S_25”: “This is a string” }
- 3:additionalProperties 额外属性定义
{
"type": "object",
"properties": {
"number": { "type": "number" },
"additionalProperties": { "type": "string" } //允许存在未被定义的字段,类型必须是字符串
}
}
“additionalProperties”: false//不允许存在未被定义的字段
{ “number”: 1600, “street_name”: “Pennsylvania”} //属性未被定义
- 4:required必需
必需存在的属性
{
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"address": { "type": "string" },
"telephone": { "type": "string" }
},
"required": ["name", "email"]
}
demo
{
"name": "William Shakespeare",
"email": "bill@stratford-upon-avon.co.uk"
}
- 4 propertyNames 对属性名称规则正则匹配
- 5 size
定义每个对象中属性个数
"minProperties": 1,
"maxProperties": 5
2.4:数组
数组包括list和元组tuple 。可以定义枚举值,唯一值,最大值,最小值,元素个数等参数。
- 1:array
数组中可以使用items关键字定义每个值的类型
{
"type": "array",
"items": { //定义每个元素类型
"type": "number"
},
"uniqueItems": true //是否允许值重复
"minItems": 2, //最小元素个数
"maxItems": 3 //最大元素个数
}
- 2:tuple元组
"prefixItems":
"items":
"contains":{},
"minContains": 2,
"maxContains": 3
"minItems": 2,
"maxItems": 3
2.5:boolean
{ “type”: “boolean” } 允许的值为true或者false
2.6:架构组合
使用下面关键字进行组合不同定义的匹配,使得对于属性定义必须满足几个或者全部的要求,允许同时根据多个标准验证一个值一样简单。类似于AND、OR。
allOf 必须对所有子模式有效
anyOf 必须对任何子模式有效
oneOf 必须符合其中一个字schema
not 都不符合
所有这些关键字都必须设置为一个数组,其中每个项目都是一个模式
1:allOf 必须都符合
demo:类型必须是string并且要求最大长度
{
"allOf": [
{ "type": "string" },
{ "maxLength": 5 }
]
}
2:anyOf 任何一个符合
3:oneOf 其中一个符合
4:not 都不符合
可以通过additionalProperties=false或者true进行不同模式间的共享或者关闭
2.7:处理xml或txt等json数据
可以对于是xml或者text等不符合json的数据定义默认的类型,比如
{ //定义该字符串中是一个txt或者xml
"type": "string",
"contentMediaType": "text/html"
}
2.8:条件属性绑定
对于某些字段间约束为一定的依赖关系,比如name属性必须依赖于age属性存在,其中一个不存在都不行。可以使用关键字
dependentRequired
同时存在或者同时不存在,可以定义双向依赖或者单向依赖
if/then/else
- dependentRequired 定义了两个字段单向依赖
"dependentRequired": {
"credit_card": ["billing_address"]
}
- if/then/else 对于子模式间的互相依赖判断,调用逻辑验证
如果country值是“”然后。。。。。。
{
"type": "object",
"properties": {
"street_address": {
"type": "string"
},
"country": {
"default": "United States of America",
"enum": ["United States of America", "Canada"]
}
},
### 上面是定义,下面可以进行判断条用不同的校验
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
},
"else": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
}
2.9:结构复杂组合示例
allof+ 依赖组成的复杂schema定义
如果满足country字段定义然后执行,否则执行,相当于is-else操作。
{
"allOf": [
{
"if": {
"properties": { "country": { "const": "United States of America" } }
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
}
},
{
"if": {
"properties": { "country": { "const": "Canada" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
}
},
{
"if": {
"properties": { "country": { "const": "Netherlands" } },
"required": ["country"]
},
"then": {
"properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
}
}
]
}
2.10:type支持的通用参数
标题或者注释:title and description
字段默认值:"default":
枚举值:enum :[] //属性含有多个值
固定值:const:某属性的值为固定的一个值,值相等才校验通过
比如: "id": {
"type": "string",
"const": "id"
},
3:构造一个复杂的schema( r e f 和 ref和 ref和def)
可以定义不同的schema,在定义相同的部分直接进行互相引用,但是在schema中没有类似URL的定位符,但是有$ref和$def
关键字进行资源位置标识。简单来说就是复用,和代码复用一样。
1:$ref关键字
使用$ref关键字引用#/definitions/Ref字段的定义。#代表这个schema,/代表跟路径。
{
"properties": {
"prop": {
"$ref" : "#/definitions/Ref"
}
},
"definitions" : {
"Ref" : {
"type" : "number"
}
}
}
4:JSON Schema开发实战
JSON Schema java实战
Java-JSON-工具/JSON-模式验证器
开发校验器推荐:
使用Jackson来处理Java代码中的JSON,使用:Java-JSON-工具/JSON-模式验证器
使用org.json API那么使用:JSON Schema everit-java实战
- 推荐在线json和json-schema校验工具:https://www.jsonschemavalidator.net/
- 推荐json转换为json-schema工具:https://tooltt.com/json2schema/
4.1:everit-org验证器
如果使用org.json解析处理json数据,则适合用everit-org检验器API。
- 1:检验器:SchemaLoader类
使用该类作为总入口,获取验证器 - 2:对于验证的冲突如何解决,或者说如何处理异常:提供了ValidationException.getCausingExceptions()获取每一个校验失败原因。
获取每一个异常并打印
try {
schema.validate(rectangleMultipleFailures); //检验
} catch (ValidationException e) { //获取异常
System.out.println(e.getMessage()); //输出异常
e.getCausingExceptions().stream() //打印每个异常
.map(ValidationException::getMessage)
.forEach(System.out::println);
}
- 3:json格式验证:为了清楚具体的json是否符合某种支持的类型,可以使用默认的校验器(ipv4等),也可以实现ValidationListener 接口验证数据。
Validator validator = Validator.builder() .withListener(new YourValidationListenerImplementation()) .build(); validator.performValidation(schema, input);
- 4:监听的严格程度:对于验证的失败数据是否继续验证可以进行设置
1:maven开发依赖
<dependency>
<groupId>com.github.everit-org.json-schema</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20201115</version>
</dependency>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
若上面依赖导入失败可用下方依赖,两者选用一个即可
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.0.63</version>
</dependency>
<dependency>
<groupId>org.everit.json</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.5.1</version>
</dependency
2:demo
json数据
{
"name":"xiaoming",
"age":99,
"like":"baskball",
"addr":{
"city":"西安",
"county":"chain"
}
}
schema规则
{
"type": "object",
"required": [],
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"like": {
"type": "string"
},
"addr": {
"type": "object",
"required": [],
"properties": {
"city": {
"type": "string"
},
"county": {
"type": "string"
}
}
}
}
}
代码测试
public static void main(String[] args) {
/*加载schema文件*/
InputStream jsonSchemaTest = jsonSchema.class.getClassLoader().getResourceAsStream("jsonSchemaTest.json");
JSONObject jsonObject = new JSONObject(new JSONTokener(jsonSchemaTest));
//将JSON schema的JSON加载到模式验证器实例中。
Schema load = SchemaLoader.load(jsonObject);
/*加载json文件*/
InputStream jsonStream = jsonSchema.class.getClassLoader().getResourceAsStream("jsonSchema1Data.json");
//验证
try {
load.validate(new JSONObject(new JSONTokener(jsonStream)));
} catch (ValidationException e) {
e.getCausingExceptions();
System.out.println("校验成功");
}
}
4.2:json-schema-validator校验器
1:maven依赖
<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.14</version>
</dependency>