参考 JSON Schema 规范(中文版)官方网站JSON Schema


对于数据对接系统来说,接口的数据入参校验尤为重要,使用javax.validation相关注解进行校验对于java对象的关联太大,数据结构变动后必须开发人员调整java对象才能满足校验。为了让数据校验和java对象解耦,研究后发现可以使用JSON Schema来实现,定义好相关的schema文件,这个文件可以放在任意可访问的地方,也不需要关心需要校验的数据是属于那个java对象。只要熟悉JSON和一些schema语法,schema文件甚至可以由非开发人员编写。

JSON Schema学习

JSON Schema是什么?

JSON Schema本身也是JSON,它表现的是数据,是描述数据结的声明性格式,并不是程序。所以,它在表现元素之间的关联关系上一定限制。

Schema声明

使用$schema来声明使用的JSON模式规范是哪个版本: draft-04

{"$schema": "http://json-schema.org/draft-04/schema#"
}

关键字

definitions

在definitions中定义的规则可以重复使用
"#"表示JSON的根节点

{"definitions": {"address": {"type": "object","properties": {"street_address": { "type": "string" },"city":           { "type": "string" },"state":          { "type": "string" }},"required": ["street_address", "city", "state"]}},"type": "object","properties": {"billing_address": { "$ref": "#/definitions/address" },"shipping_address": { "$ref": "#/definitions/address" }}
}

title

标题

description

详细的说明

type

数据类型,支持:array,object,string,Integer,number, null;

properties

type是object时具有成员属性

required

properties中的必填属性都放在这里

{"$schema": "http://json-schema.org/draft-04/schema#","type": "array","items": {"type": "object","properties": {"attachmentCode": {"type": "string"},"attachmentFileName": {"type": "string"},"md5": {"type": "string"}},"required": ["md5"]}
}

不同type下校验关键字

array

  • items 数组中的成员属性规则,可以包含不同类型的成员变量规则
{"type": "array","items": [{"type": "object","properties": {"attachmentCode": {"type": "string"},"attachmentFileName": {"type": "string"},"fileType": {"type": "string"},"dataTimestamp": {"$ref": "#/must_time"},"md5": {"type": "string"}}},{"type": "string","minLength": 5},{"type": "number","minimum": 10},{"type": "string"}]
}
  • additionalItems 表达除了已申明的元素外,剩余的元素需要满足的条件
{"type": "array","items": [{"type": "string","minLength": 5},{"type": "number","minimum": 10}],"additionalItems": {"type": "string","minLength": 2}
}

上面的JSON Schema的意思是,待校验JSON数组第一个元素是string类型,且可接受的最短长度为5个字符,第二个元素是number类型,且可接受的最小值为10,剩余的其他元素是string类型,且可接受的最短长度为2。

  • minItems 最少存在的元素数量
  • maxItems 最大存在的元素数量
  • uniqueItems 元素是否唯一
  • contains 包含,只要对数组中的一项或多项进行验证通过即可
{"type": "array","contains": {"type": "number"}
}["life", "universe", "everything", 42] // OK,包含一个number元素
["life", "universe", "everything", "forty-two"]  // not OK,不包含number元素
[1, 2, 3, 4, 5] // OK

object

  • minProperties, maxProperties

规定最少、最多有几个属性成员。

  • additionaProperties

规定object类型是否允许出现不在properties中规定的属性,只能取true/false。

integer/number

  • **multipleOf: **该关键字的值是一个大于0的number,即可以是大于0的int,也可以是大于0的float。

只有待校验的值能够被该关键字的值整除,才算通过校验。

如果含有该关键字的JSON Schema如下:{"type": "integer",
"multipleOf": 2
}那么,2、4、6都是可以通过校验的,但是,3、5、7都是无法通过校验的,
当然了,2.0、4.0也是无法通过校验的。如果含有multipleOf关键字的JSON Schema如下:
{ "type": "number", "multipleOf": 2.0 }
那么,2、2.0、4、4.0都是可以通过校验的,但是,3、3.0都是无法通过校验的。
  • maximum:

元素可以通过校验的最大值

  • exclusiveMaximum:

该关键字通常和maximum一起使用,当该关键字的值为true时,表示待校验元素必须小于maximum指定的值;当该关键字的值为false时,表示待校验元素可以小于或者等于maximum指定的值。

  • minimum:

元素可以通过的最小值

  • exclusiveMinimum:

exclusiveMaximum相反

string

  • maxLength:字符串通过校验的最大长度
  • minLength:字符串通过校验的最小长度
  • pattern:正则匹配
  • format:
format只能是以下值:
date-time(时间格式)、email(邮件格式)、hostname(网站地址格式)、
ipv4、ipv6、uri、uri-reference、uri-template、json-pointer。

所有类型都可以用的关键字

  • dependencies

规定某些成员的依赖成员,不能在依赖成员缺席的情况下单独出现,属于数据完整性方面的约束。
有"credit_card"属性,则"billing_address" 属性不能缺席:

{"type": "object","dependencies": {"credit_card": ["billing_address"]}
}
  • enum、

该关键字的值是一个数组,该数组至少要有一个元素,且数组内的每一个元素都是唯一的。
如果待校验的JSON元素和数组中的某一个元素相同,则通过校验。否则,无法通过校验。
该数组中的元素值可以是任何值,包括null。

  • const、

元素被限定为一个常量值

  • allOf、

必须满足全部的检验才能通过

  • anyOf、

满足一个或多个校验可以通过

  • oneOf、

只能满足一个校验才能通过

  • not、

不满足这个校验才能通过

  • default、

关键字指定一个默认值

JSON Schema编写

java对象生成schema工具reinert

<dependency><groupId>com.github.reinert</groupId><artifactId>jjschema</artifactId><version>1.16</version>
</dependency>

实际应用场景中,重复引用的情况比较多,这里说明下引用的使用

  1. 将公共的校验规则提取出来成独立的schema文件
  2. 两种引用方式:
    1. 先用id定义,在使用id定义,在使用id定义,在使用ref引用

在draft 4 中,id只是id(没有id 只是 id(没有id只是id(没有符号)

{"$schema": "http://json-schema.org/draft-04/schema#","description": "定义时间字段的匹配规则","must_time": {"description": "必填时间字段规则","oneOf": [{"type": "string","pattern": "(\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2})|(\\d{4}-\\d{1,2}-\\d{1,2})$|^\\d{1,13}$"},{"type": "number"}]},"not_time": {"description": "非必填时间字段","oneOf": [{"type": "string","pattern": "(\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2})|(\\d{4}-\\d{1,2}-\\d{1,2})$|^\\d{1,13}$"},{"type": "number"},{"type": "null"}]}}
{"$schema": "http://json-schema.org/draft-04/schema#","type": "array","id": "file:/E:/Time.json", //定义引用"items": {"type": "object","properties": {"attachmentCode": {"type": "string"},"attachmentFileName": {"type": "string"},"fileType": {"type": "string"},"dataTimestamp": {"$ref": "#/must_time" //直接使用引用中的规则,对于重复引用的书写较为友好},"md5": {"type": "string"}}}
}
  1. 直接$ref引用文件:
{"attachment": {"$ref": "file:/E:/Attachment.json" //使用整个schema文件的校验规则"$ref": "file:/E:/Attachment.json#/age" //使用文件根节点下的age的校验规则"$ref": "file:///Attachment.json#/age" //linux环境使用文件根节点下的age的校验规则}
}

JSON Schema使用

因为需要使用校验的结果,所以使用了fge这个库,性能上会差一点,支持草案draft-04 draft-03
官方也提供了一些开源工具schema工具:http://json-schema.org/implementations.html

<dependency><groupId>com.github.java-json-tools</groupId><artifactId>json-schema-validator</artifactId><version>2.2.14</version>
</dependency>

代码实现

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fzzn.water.check.core.factory.CheckBuildFactory;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jackson.JsonNodeReader;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchemaFactory;import java.io.FileReader;
import java.util.Iterator;sonNode schemaJson = new JsonNodeReader().fromReader(new FileReader("schema文件路径"));
JsonNode dataNoe = JsonLoader.fromString("待校验的JSON字符串");
ProcessingReport processingMessages = JsonSchemaFactory.byDefault().getValidator().validate(schemaJson, dataNoe, true);//true: 全部校验完再返回
System.out.println(processingMessages.isSuccess());
Iterator<ProcessingMessage> iterator = processingMessages.iterator();
JSONObject jsonNode;
while (iterator.hasNext()) {ProcessingMessage message = iterator.next();jsonNode = JSONUtil.parseObj(message.asJson().toString());System.out.println("------>" + jsonNode.toString());System.out.println("======>" + message);
}

输出示例:

------>{"schema":{"pointer":"/items/properties/md5","loadingURI":"#"},"instance":{"pointer":"/0/md5"},"level":"error","expected":["string"],"message":"instance type (null) does not match any allowed primitive type (allowed: [\"string\"])","found":"null","domain":"validation","keyword":"type"}
======>error: instance type (null) does not match any allowed primitive type (allowed: ["string"])level: "error"schema: {"loadingURI":"#","pointer":"/items/properties/md5"}instance: {"pointer":"/0/md5"}domain: "validation"keyword: "type"found: "null"expected: ["string"]

拿到JSON格式的校验的结果,就可以针对性的处理了。

JSON Schema校验数据相关推荐

  1. 如何利用JSON Schema校验JSON数据格式

    最近笔者在工作中需要监控一批http接口,并对返回的JSON数据进行校验.正好之前在某前端大神的分享中得知这个神器的存在,调研一番之后应用在该项目中,并取得了不错的效果,特地在此分享给各位读者. 什么 ...

  2. java schema校验_Json Schema 校验json,java代码示例

    Json Schema 校验json,java代码示例 1.json schema 入门请参考下面两篇博客 1.1Json Schema 快速入门 1.2Json Schema 简介 2.java代码 ...

  3. json schema多种形式_什么是JSON Schema?

    什么是JSON Schema? 如果你曾经使用过XML Schema,RelaxNG或ASN.1,那么你很可能已经知道什么是JSON Schema,并且可以跳过本文的阅读.如果你是头一次听说,或者听过 ...

  4. json schema多种形式_什么是JSON Schema?及其应用方式......

    如果你曾经使用过XML Schema,RelaxNG或ASN.1,那么你很可能已经知道什么是JSON Schema,并且可以跳过本文的阅读.如果你是头一次听说,或者听过过这个词汇但不了解,那么你来对地 ...

  5. 基于JSON Schema的前端可视化活动编辑器

    先看效果,为一个可视化活动编辑器. 演示地址:form.lljj.me/vue-editor.- 项目地址:github.com/lljj-x/vue-- 基于 JSON Schema 开箱即用的简单 ...

  6. Python中json自定义jsonschema进行json数据格式校验

    一.python中jsonschma库 python中有时候我们想对json数据进行键值对(key,value)数据的数据格式进行校验,因为数据类型不符合业务逻辑会导致业务逻辑代码执行报错,这时候我们 ...

  7. 【Python】Json Schema的使用【原创】

    Json Schema在Python中的应用 一. 背景 二.概述 三.介绍 四.Python中使用 五.例子 六.参考 一. 背景 之前在做容器发布系统的时候,在部署时需要对提交的deploymen ...

  8. json schema多种形式_Json Schema简介

    1. 引言 什么是Json Schema? 以一个例子来说明 假设有一个web api,接受一个json请求,返回某个用户在某个城市关系最近的若干个好友.一个请求的例子如下: { "city ...

  9. json schema 关键字速查

    相关文章: [1] Understanding JSON Schema [2] Json Schema 快速入门 [3] Json Schema简介 1 引言 1.1 背景 json格式中提供如下A( ...

最新文章

  1. spring MVC做form提交Neither BindingResult nor plain target object for bean name 'command' available...
  2. Web本地计算发展史
  3. JAVA数组扁平化整合_JS数组扁平化(flat)方法总结详解
  4. 碎片化学习不是学习碎片,看这篇了解碎片化学习的真相
  5. Android底部导航栏实现(一)之BottomNavigationBar
  6. IntelliJ IDEA for Mac 如何创建普通的Java项目_创建项目_新建项目
  7. MySQL 安全性知识要点
  8. delphi listview 添加数据 慢_ListView 的缓存机制
  9. 单纯形法只有两个约束条件_教学 | 线性规划 7 :单纯形法的引入
  10. 华为lab-rs-v1-2.3_OSPF基础
  11. 关键词组合工具-免费在线关键词标题组合工具
  12. 米思齐——简易呼吸灯
  13. 优麒麟 20.04 LTS Pro安装Canon LBP2900打印机
  14. 我的大脑越来越喜欢那些碎片化的、不用思考的文章了!
  15. c语言中ifelse语句的例子,ifelse语句例子
  16. Java Web实训-西蒙购物网
  17. pdf怎么删除其中一页?
  18. 深入理解Android L新特性之 页面内容amp;共享元素过渡动画
  19. 门级仿真经验(SDF反标及其工作原理)
  20. 简单的记账方法有哪些?

热门文章

  1. Vue的MVVM模型和双向数据绑定原理
  2. 手牵手,简单的甜蜜。
  3. 【软件工程】 第0次个人作业
  4. 首次安装linux 连接wifi
  5. 大牛的深度学习面试经验
  6. “收费”了微信,红了Line
  7. 深度学习2.1二分类(Binary Classification)
  8. idea替换的快捷键
  9. 现场记录:Oracle年月补零方法;Oracle yyyy-m转yyyy-mm方法。
  10. 10/100Base+1000Base/百兆/千兆网络接线,568A+568B线序,交叉线、直连线意义等的探讨