网站首页 > 博客文章 正文
json schema是用来验证和描述json对象结构的。
在线验证:https://www.jsonschemavalidator.net/
json schema 编辑器,推荐VSCode,写上"$schema": "https://raw.githubusercontent.com/json-schema-org/json-schema-spec/draft-07/schema.json#"后有自动补全。如下图:
hello json schema world
举例说明一下,比如一个不存在的交友网站的个人信息(名字性取向身高体重联系方式)json格式及其schema是下面这样的:
{ "name": "张三", "age": 25, "sexualOrientation": "女", "height_cm": 175, "weight_kg": 65.1, "contactInfo": { "email": "zhangsan@gmail.com", "phone": "13800000000" } }
{ "type": "object", "properties": { "name": { "type": "string" }, "age": { "$comment": "嗯,不能小于14岁", "type": "integer", "minimum": 14, "maximum": 100 }, "sexualOrientation": { "type": "string", "enum": [ "男", "女", "双性恋" ] }, "height_cm": { "type": "integer" }, "weight_kg": { "type": "number" }, "contactInfo": { "type": "object", "properties": { "email": { "type": "string", "pattern": ".+@.+" }, "phone": { "type": "string", "pattern": "\\d{11}" } } } } }
json schema本身也是一个json对象,在type字段指定了类型,可以是"array", "boolean", "integer", "null", "number", "object", "string"。如果是object类型,那可以在properties里面描述每一个字段的类型。
type可以是一个数组,表示可以是多个类型。比如下面的json schema:
{ "type": [ "string", "integer" ] } "string"
可以通过验证,这是一个字符串3
可以通过验证,这是一个整数1.5
不能通过验证,这是一个浮点数{ }
不能通过验证,这是一个object数组
如果type是array,name可以在items里描述数组元素的类型,items可以是一个对象也可以是一个数组。
比如下面这个schema,定义了一个对象,它有2个字段array1和array2,array1的items是一个对象,array2的items是一个数组。
{ "type": "object", "properties": { "array1": { "type": "array", "items": { "type": "number" } }, "array2": { "type": "array", "items": [ { "type": "number" }, { "type": "string" } ] } } }
有什么区别了?items是数组那么是分别定义每一个元素;items是对象的话表示定义所有元素。举例说明一下:
{ "array1": [ 1 ], "array2": [ 1, "2" ] }
验证通过,没啥好解释的{ "array1": [ 1 ], "array2": [ 1, 2 ] }
验证失败
schema里要求arry2的
第二个元素是字符串
但是2不是字符串
{ "array1": [ 1, 2, "3" ], "array2": [ 1, "2" ] }
验证失败
schema里array1的items是一个对象
这表示要求其所有的元素都是数字
"3"不是数字
json schema是“规则”
json schema定义的是“规则”,理解这一点很重要。
尤其是,如果你和我一样先了解了xsd,先入为主的觉得XML Schema和json schema都是“schema”而且xml和json都是树桩结构,于是觉得它们应该差不多,那就错了。xsd是严格的面向对象设计思路,xsd定义的是对象,xml是xsd定义的对象的实例。而json schema只是规则,json对象和json schema之间的关系是json对象符合json schema定义的规则,或者,不符合。
理解这点对于理解后面的复杂一点的概念很重要。
并且,默认情况下,json schema只验证出现了的内容(对象字段或者数组元素)是否符合规则,而不验证没出现的。
举例说明,对于如下的schema:
{ "type": "array", "items": { "type": "object", "properties": { "field": { "type": "string" } } } } []
空数组
符合规则
它没有出现元素
没出现的就不验证
[ { "field": "2" } ]
也符合规则
没啥好说的
[ { "field": 2 } ]
验证失败,出现了field
但是类型错误
[ { "field": "value" }, { } ]
也符合规则
数组中的第二个元素没出现任何字段
没出现的不验证
[ { "field": "value" }, { }, { "field1":"value" } ]
还是符合规则
规则里没要求field必须出现
同时没对field1定义规则
所以这也是对的
复用:ref和definitions
如果把名字定义成姓和名,而一个人有名字,他有父母,父母也有名字。那姓名的规则定义就需要复用。
上例子:
{ "$schema": "https://raw.githubusercontent.com/json-schema-org/json-schema-spec/draft-07/schema.json#", "type": "object", "properties": { "name": { "$ref": "#/definitions/Name" }, "parents": { "type": "object", "properties": { "father": { "$ref": "#/definitions/Name" }, "mother": { "$ref": "#/definitions/Name" } } } }, "definitions": { "Name": { "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" } } } } }
allOf,oneOf,anyOf
既然json schema是规则,那么,就可以要求一个对象同时满足多个规则,或者满足多个规则之一。
allOf
allOf是一个数组,要求json对象必须满足数组里所有元素定义的规则。
举例:为爱鼓掌一男一女,都有姓名年龄,不过女的年龄不得小于14岁,否则,去查查刑法。
{ "$schema": "https://raw.githubusercontent.com/json-schema-org/json-schema-spec/draft-07/schema.json#", "type": "object", "properties": { "male": { "$ref": "#/definitions/Person" }, "female": { "allOf": [ { "$ref": "#/definitions/Person" }, { "type": "object", "properties": { "age": { "type": "integer", "minimum": 14 } }, "$comment": "注意这里定义required字段,age是必须出现的", "required": [ "age" ] } ] } }, "definitions": { "Person": { "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" } } } } }
oneOf和anyOf的用法和allOf一致。含义,字面意思。
需要注意的是,oneOf是指其中一个,如果同时符合oneOf下面定义的多个规则,那是会验证不过的。anyOf是任意一个或者多个。
比如下面这个很二的规则(实际上没人会这么定义)
{ "$schema": "https://raw.githubusercontent.com/json-schema-org/json-schema-spec/draft-07/schema.json#", "oneOf": [ { "type": "integer", "minimum": 14 }, { "type": "integer", "minimum": 20 } ] }
用14去验证,是通过的,满足第一条,用20去验证,是无法验证通过的,因为20同时满足了2条。
if,then,else
看名字就知道是干啥的,不过这个if条件怎么写啊。再提一次,json schema定义的是规则。
if里面不是我们常见的条件,而是规则,如果json对象满足if下面定义的规则,那么就用then下面的规则去验证该json,否则就用else下面的规则去验证。当然then以及else可不存在(这两个要都不存在那写if干嘛啊)
不正经示例,如果心爱的女孩子单身状态,那么可以执行“聊骚”操作,如果有男朋友,那可以执行“挖墙脚操作”,如果已婚……那可以在“天涯何处无芳草”,“默默守护”操作中选一个,但是不能“当隔壁老王”。当然前提是知道女孩子状态,所以girlState是required。
{ "$schema": "https://raw.githubusercontent.com/json-schema-org/json-schema-spec/draft-07/schema.json#", "type": "object", "properties": { "girlState": { "type": "string", "enum": [ "单身", "有男朋友", "已婚" ] } }, "allOf": [ { "if": { "type": "object", "properties": { "girlState": { "const": "单身" } } }, "then": { "type": "object", "properties": { "action": { "const": "聊骚" } } } }, { "if": { "type": "object", "properties": { "girlState": { "const": "有男朋友" } } }, "then": { "type": "object", "properties": { "action": { "const": "挖墙脚" } } } }, { "if": { "type": "object", "properties": { "girlState": { "const": "已婚" } } }, "then": { "type": "object", "properties": { "action": { "type": "string", "enum": [ "天涯何处无芳草", "默默守护" ] } } } }, { "if": { "type": "object", "properties": { "girlState": { "const": "已婚" } } }, "then": { "not": { "type": "object", "properties": { "action": { "const": "当隔壁老王" } } } } } ], "required": [ "girlState" ] }
可以思考一下为什么用的是allOf
对于上面的schema
{ "girlState": "已婚", "action": "当隔壁老王" }
验证失败{ "girlState": "有男朋友", "action": "挖墙脚" }
验证通过
虽然不道德
additionalItems和additionalProperties设置为false可以禁止未定义的元素/字段出现。
不过additionalProperties设为false这个很不好用。
vscode有自动补全,其它的字段看补全的名字就知道作用了。
猜你喜欢
- 2024-10-17 .NET配置文件大揭秘:轻松读取JSON、XML
- 2024-10-17 [NewLife.XCode]反向工程(自动建表建库大杀器)
- 2024-10-17 Java 使用fastjson将json字符串转为泛型对象
- 2024-10-17 python 实例分析——发送json数据相关实现技巧
- 2024-10-17 比较一下XML, JSON和YAML(xml数据和json数据)
- 2024-10-17 Protobuf的简单介绍、使用和分析(protobuf的作用)
- 2024-10-17 详解电子表格中的json数据:序列化与反序列化
- 2024-10-17 【Qt教程】使用 QJson 处理 JSON(qt线程使用)
- 2024-10-17 引入 jackson-dataformat-xml 后,默认响应结果是 json 还是 xml?
- 2024-10-17 C# XML序列化、JSON序列化和Binary序列化的简单例子
你 发表评论:
欢迎- 373℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 369℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃初次使用IntelliJ IDEA新建Maven项目
- 352℃Maven技术方案最全手册(mavena)
- 349℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 348℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 346℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 344℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)