JsonSchema学习笔记
Posted 守林鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JsonSchema学习笔记相关的知识,希望对你有一定的参考价值。
一、什么是JsonSchema?
JsonSchema本质是一套规则,用来定义Json的数据格式。
例如定义人员信息,包含名字、年龄、生日。需要对这个人员信息的格式有约定,名字必须是字符串,年龄必须是整数,生日必须是日期类型的字符串。举例一个Json数据
"name":"shoulinniao",
"age":24,
"birthday":"1998-11-11"
想要校验人员信息的JsonSchema可以是这么一个Json格式的规则
"type":"object",
"properties":
"name":
"type":"string"
,
"age":
"type":"integer"
,
"birthday":
"type":"string",
"format":"date"
在线生成JsonSchema的工具:https://www.jsonschema.net/home
在线校验JsonSchema的工具:https://jsonschemalint.com/#!/version/draft-07/markup/json
JsonSchema版本有3个,draft-04、draft-06、draft-07
版本声明关键字$schema
"$schema":"http://json-schema.org/draft-07/schema#"
二、类型关键字
定义一种数据结构首先从数据类型出发,例如学Java之初的八种基本数据类型。JsonSchema作为一套成熟的规则,也有自己的类型定义描述。
从上面的例子可以很容易看到"type"是定义类型的关键字,类型可以是"object","string","integer"。具体的数据类型有以下几种
- object 对象,可以包含多个字段
- string 字符串
- number 数字,包括浮点数和消暑
- integer 整数
- array 数组
- boolean 布尔,只有true和false两个合法值
- null 空,只有null一个合法值
三、类型额外特定参数
1.字符串string
- minLength:最小长度
- maxLength:最大长度
- pattern:正则表达式
- format:字符串格式,内容可以是date、time、data-time、email、hostname等
"type":"string", "minLength":11, "maxLength":100, "pattern":"^\\d4(\\-|\\/|\\.)\\d1,2\\1\\d1,2$", "format":"date"
2. 数值number和integer参数都相同
- 满足某个数的倍数:multipleOf
- 最小值:minimum
- 最大值:maximum
- 开区间最小值:exclusiveMinimum
- 开区间最大值:exclusiveMaximum
"type":"number",
"multipleOf":5,
"minimum":66,
"maximum":99,
"exclusiveMinimum":1234,
"exclusiveMaximum":8888
这里显然区间最值与最大最小值矛盾,但这是合法的JsonSchema。
注意:这个例子如果用draft-04则会报错,其他两个版本则校验正常。
3. 布尔boolean和空值null类型没有额外的类型特定参数
4. 数组array
- items:成员类型,对应值可以是一个JsonSchema,规定数组元素的JsonSchema,也可以是一个JsonSchema数组,要求数组元素按照JsonSchema数组的要求一一对应。
- additionalItems:true/false,是否允许额外成员类型,仅当items是数组Schema才起作用,额外元素追加在数组后面。
- minItems:数组元素最小个数
- maxItems:数组元素最大个数
- uniqueItems:true/false,数组元素是否唯一
例如以下Schema,定义了第一个元素必须是数值,第二个元素必须是字符串,允许追加其他元素在第二个元素后,并且元素个数必须大于等于2,小于等于54,元素值必须唯一的数组类型。
"type":"array",
"items":[
"type":"number"
,
"type":"string"
],
"additionalItems":true,
"minItems":2,
"maxItems":54,
"uniqueItems":true
举例合适的Json数组 [1998,"shoulinniao",true]
5. 对象object
最常用的类型,Json格式一层套一层
- properties:成员的schema,json格式,key是对象字段名,value是又一个schema
- patternProperties:批量定义成员的schema,正则匹配多个key对应一种schema
- required:必须出现的成员,数组格式
- dependencies:成员依赖关系,json格式,key是字符串,value是字符串数组,表示key属性出现value数组里的所有属性不能缺席
- additionalProperties:true/false,是否允许出现properties中没有定义的属性
- minProperties:最少属性个数
- maxProperties:最多属性个数
例如开头举例的人员信息可以用以下schema校验
"type": "object",
"properties":
"name":
"type": "string"
,
"age":
"type": "integer"
,
"birthday":
"type": "string",
"format": "date"
,
"required": [
"name"
],
"dependencies":
"name": [
"age",
"birthday"
]
四、逻辑组合
- allOf:满足数组里所有的schema,数组格式
- anyOf:满足任意多个schema,数组格式
- oneOf:必须满足且仅满足其中一个schema,数组格式
- not:不能满足not对应的schema,json格式
五、复杂结构
- 定义:没有固定关键字,习惯在根节点的"definations"下定义可以多次引用的schema
- $id:唯一标识定义中的属性,可以通过id引用,而不需要根节点下的完整路径
- $ref:引用,路径以#开头代表根节点或者ID
schema和数据举例
"definitions":
"bbox":
"$id": "bbox_schema",
"type": "array",
"item":
"type": "number"
,
"minLength": 4,
"maxLength": 4
,
"type": "object",
"properties":
"plate_bbox":
"$ref": "#/definitions/bbox"
,
"table_bbox":
"$ref": "bbox_schema"
"plate_bbox": [3,4,5,6],
"table_bbox": [7,7,3,4]
六、通用关键字
enum:枚举数组,值必须选择其中一个,数组格式。
以下的仅用于描述,不影响校验效果
- title:标题
- description:描述
- default:默认值
- example:举例说明
- "$comment":批注
七、Java代码运用
1.导入依赖包
<dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema</artifactId>
<version>1.14.0</version>
</dependency>
2.校验
public static void main (String[]args)
String json = "\\"plate_bbox\\":[3,4,5,6],\\"table_bbox\\":[7,7,3,4]";
JSONObject jsonObject = new JSONObject(json);
String jsonSchema = "\\"definitions\\":\\"bbox\\":\\"$id\\":\\"bbox_schema\\",\\"type\\":\\"array\\",\\"item\\":\\"type\\":\\"number\\",\\"minLength\\":4,\\"maxLength\\":4,\\"type\\":\\"object\\",\\"properties\\":\\"plate_bbox\\":\\"$ref\\":\\"#/definitions/bbox\\",\\"table_bbox\\":\\"$ref\\":\\"bbox_schema\\"";
JSONObject jsonSchemaObject = new JSONObject(jsonSchema);
//两种方法确定版本
// 1、在JsonSchema里把版本定义好了,否则默认加载4版本,如果加载6、7版本的特定内容会失败
Schema schema = SchemaLoader.load(jsonSchemaObject);
// 2、没有在JsonSchema里定义版本,声明加载器的版本
SchemaLoader schemaLoader = SchemaLoader.builder().schemaJson(jsonSchemaObject).draftV7Support().build();
schema = schemaLoader.load().build();
// 校验
schema.validate(jsonObject);
以上是关于JsonSchema学习笔记的主要内容,如果未能解决你的问题,请参考以下文章