一、背景

根据实际需求,发现前后端都需要对数据进行校验,且校验字段较多。为避免在代码中加入繁琐的判断,且能前后端保持统一标准,我们使用JSON schema规范来进行数据的校验。

二、JSON Schema

2.1 定义

json-schema 中文意思是 JSON的模式。定义一个JSON的规范,对数据的格式进行约束。比如数据的类型,数字number,字符串 string, 对象Object;数字的大小和区间范围;是否要求必填等等;

2.2 例子

2.2.1 要求

如下是一个校验字段fieldA,fieldB,fieldC的样例。我们要求fieldA是字符串,且值为testString;fieldB是数字类型,大于0(不等于0);三个字段为必填字段。

{"type": "object","properties": {"fieldA": {"type": "string","enum": ["testString"]},"fieldB": {"type": "number","exclusiveMinimum": 0}},"required": ["fieldA","fieldB","fieldC"]
}

2.2.2 待验证数据

{"fieldA": "test","fieldB": 0
}

2.2.3 验证

在线验证地址 https://jsonschemalint.com/#!/version/draft-07/markup/json

2.3 版本

json schema 存在多个版本,当前最新版本为draft-07。 不同版本之间规范也不同。部分实现json schema框架默认draft4,可能大家使用过程中会造成麻烦。为了统一规范,可以在后续实现中,显式设置版本号。当然也可是每条检验规范显示设置一个版本号,不过那样太麻烦了。

版本 exclusiveMaximum exclusiveMaximum
draft-04 取值为 true false,与minimum结合使用,举例 a>0,则exclusiveMaximum: true, minimum:0 取值为 true false,与maximum结合使用,举例 a<0,则exclusiveMaximum: true, maximum:0
draft-07 数字,举例 a>0,则exclusiveMinimum : 0 数字,举例 a<0,则exclusiveMaximum: 0

三、实现

第二部分只是定义了一个规范,现在讲述一下如何实现。虽然JSON schema是脱离语言的,但是实现还是跟语言相关的。

3.1 前端

框架 地址 介绍 是否选用
ajv https://github.com/ajv-validator/ajv draft-07, -06, -04 for Node.js and browsers - supports custom keywords and $data reference (MIT) 选用
djv https://github.com/korzio/djv draft-06, -04 for Node.js and browsers (MIT)
Hyperjump JSV https://github.com/jdesrosiers/json-schema 2019-09, draft-07, -06, -04 Built for Node.js and browsers. Includes support for custom vocabularies. (MIT)
vue-vuelidate-jsonschema https://github.com/mokkabonna/vue-vuelidate-jsonschema draft-06 (MIT)
@cfworker/json-schema @cfworker/json-schema 2019-09, draft-07, -06, -04 Built for Cloudflare workers, browsers, and Node.js (MIT)

选用ajv。ajv 是最优的选择。
ajv 是对 JSON Schema 支持最全的一个库;
性能在现有的库中也很优越, 排在第二位,;
排第一位 djv 没有实现 JSON Schema 的最新特性, 我们需要使用最新版规范draft-07;
ajv 与 djv 性能上很接近, 且 ajv比djv的性能更优越;
ajv的社区比djv活跃;

3.1.1 引入

npm install ajv

3.1.2 demo代码

// or ESM/TypeScript import
import Ajv from "ajv"
// Node.js require:
const Ajv = require("ajv")const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
// 规范
const schema = {type: "object",properties: {r93#:{ type:"string", enum:["a"]},r94#:{ type:"string", enum:["b"]},r156#:{anyOf:[{type:"number",exclusiveMinimum:0},{type:"number",exclusiveMaximum:0}]},},required: ["r93#","r94#",,"r156#"],additionalProperties: false,
}
// 待校验的数据
const data = {r156#: 0,r93#: "1",r94#: "b",
}const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)

3.2 后端

框架 地址 介绍 是否选用
networknt/json-schema-validator https://github.com/networknt/json-schema-validator draft-07, -06, -04 Support OpenAPI 3.0 with Jackson parser (Apache License 2.0) 选用
everit-org/json-schema everit-org/json-schema draft-07, -06, -04 (Apache License 2.0)
snowy-json https://github.com/ssilverman/snowy-json 2019-09, draft-07, -06 Uses Maven for the project and Gson under the hood. (GNU Affero General Public License v3.0)

后端选用networknt框架。根据框架比较,

1.networknt是耗时最少的;

2.支持jackson;

3.最小侵入,只引入一个jar包,不会造成冲突;

3.支持高版本jdk,jdk1.8以上,;

4.社区比较活跃。

3.2.1 引入

<dependency><groupId>com.networknt</groupId><artifactId>json-schema-validator</artifactId><version>1.0.72</version>
</dependency>

3.2.2 demo代码

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;import java.util.HashMap;
import java.util.Map;public class JsonSchemaUtil {public static boolean getPatternIdByRule(String checkExpression, JsonNode json) {if (StringUtils.isBlank(checkExpression)) {return false;}try {ObjectMapper mapper = new ObjectMapper();JsonNode rootNode = mapper.readTree(checkExpression);// 需要明确指定版本为draft7JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)).objectMapper(mapper).build();JsonSchema newSchema = validatorFactory.getSchema(rootNode);if (CollectionUtils.isNotEmpty(newSchema.validate(json))) {return false;} else {return true;}} catch (Exception e) {e.printStackTrace();}return false;}public static void main(String[] args) {ObjectMapper newMapper = new ObjectMapper();Map<String, Object> ruleMap = new HashMap<>();ruleMap.put("r156#", 0);ruleMap.put("r93#", "1");ruleMap.put("r94#", "b");JsonNode json = newMapper.valueToTree(ruleMap);System.out.println("空对象 校验成功 " + getPatternIdByRule("{}", json));System.out.println("r156#  校验失败 " + getPatternIdByRule("{ \"type\":\"object\", \"properties\":{ \"r156#\":{\"anyOf\":[{\"type\":\"number\",\"exclusiveMinimum\":0},{\"type\":\"number\",\"exclusiveMaximum\":0}]}}, \"required\":[\"r156#\"] }", json));System.out.println("r93#   校验失败 " + getPatternIdByRule("{ \"type\":\"object\", \"properties\":{ \"r93#\":{ \"type\":\"string\", \"enum\":[\"a\"] } },\"required\": [\"r93#\"] } ", json));System.out.println("r94#   校验成功 " + getPatternIdByRule("{ \"type\":\"object\", \"properties\":{ \"r94#\":{ \"type\":\"string\", \"enum\":[\"b\"] } },\"required\": [\"r94#\"] } ", json));}}

#四、坑

有些坑是要避开的

  1. 要显示设置json schema的版本?

不同版本的json schema规范是不一样的,可详见 2.3 版本的 介绍,当前最新版本是draft07。举例,后端networknt框架 可调用builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7))指定

  1. ajv 和 networknt 是目前最好的选择吗?

通过比较,ajv 和 networknt 是目前最好的选择。当然大家可以根据实际情况选择

3.不同框架使用的JSONjar一样吗?

不一样。比如 后端networknt框架使用jackson, 后端everit框架使用org.json

参考资料

json schema介绍 https://blog.csdn.net/liuxiao723846/article/details/108523139

json schema介绍 https://cloud.tencent.com/developer/article/1617902

json schema介绍 https://www.shouxicto.com/article/2783.html

在线编辑和校验 https://jsonschemalint.com/#!/version/draft-07/markup/json

json schema实际运用相关推荐

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

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

  2. laravel 验证器怎么验证json对象_Postman使用tv4进行JSON Schema结构验证和断言

    JSON Scheme简介 对于JSON格式的请求数据或者响应数据,在不同的数据和场景下往往会有一部分动态的值及字段.此时我们可以使用JSON Scheme Validator(JSON结构验证)来验 ...

  3. rest-assured之Schema validation(包括JSON Schema validation及Xml Schema validation)

    rest-assured从2.1.0版本开始支持  Schema 验证,包括JSON Schema validation及Xml Schema validation.我们之前断言响应体都是一个一个字段 ...

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

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

  5. json schema如何约束为小数_如何使用jsonschema进行接口响应断言

    一,JSONSchema的概念 JSONSchema是一种用来描述JSON数据的一种JSON数据结构.JSON Schema也有版本,目前的版本有 Draft 7,Draft 6,Draft 4 和D ...

  6. Json Schema快速入门

    Json Schema快速入门 JSON 模式是一种基于 JSON 格式定义 JSON 数据结构的规范.它被写在 IETF 草案下并于 2011 年到期.JSON 模式: 描述现有数据格式. 干净的人 ...

  7. Json Schema的使用

    直接上案例: 在Web Api通讯中,客户端发送json数据,服务端反序列化json(json与某个类形成对应关系),在某些情况下,需要校验其上传的json是否合法. 服务端是使用Json.net(n ...

  8. 3 分钟了解 JSON Schema

    大家好,我不是鱼皮. 幸运又不幸,我是一名程序员,他也是一名程序员. 周末,我在开发网站,他在开发游戏,两个人一起写代码,一起写 Bug 头秃,竟也有了一丝别样的浪漫,好不自在! 今天,他遇到了一个后 ...

  9. JSON Schema

    XML有XML Schema,有Schema的好处就是可以校验文件是否符合规范,在代码提示上也会有许多好处.JSON Schema用于JSON验证. 如果说JSON是盛放数据的袋子,那么JSON Sc ...

  10. 如何快速写出Json Schema,校验Json Schema

    本文首发于微信公众号: [软测小生] 得到一个Json文件,如何快速的去测试呢? 难道是一个个节点的去验证吗?那显然效率太低了. 一般推荐使用Json Schema(一种Json的数据结构定义)去校验 ...

最新文章

  1. 2022-2028年中国音像制品行业投资分析及前景预测报告
  2. ECCV20 3D目标检测新框架3D-CVF
  3. 打开深度神经网络黑箱:竟是模块化的?图聚类算法解密权重结构 | ICML 2020
  4. 如何修改Ubuntu Linux的时间
  5. java开发课程表_展示Java开发人员课程包
  6. linux下搜狗输入法无法输入中文解决方法
  7. 2019计算机国二操作题,2019年3月计算机二级C++操作练习题及答案(十二)
  8. 从源码角度详解Java的Callable接口
  9. JAVA导出excel如何设置表头跨行或者跨列,跪求各位大神了
  10. 解决问题—麦肯锡方法:解决问题的七个步骤
  11. 用四叉树加速碰撞检测
  12. 转账设计测试用例-----必背
  13. 两种领导力:温柔与严厉
  14. layui前端项目打包方法_layui封装模块基础教程
  15. 为什么每次开机都要进行磁盘检查?
  16. JS每晚24:00更新某方法
  17. 微信小程序春天来了 安卓程序员进入冬眠?
  18. WARNING: One of the plugins you are using supports Java 8 language features. To try the support buil
  19. UEFI开发与调试--edk2中的基础组件
  20. SSD1963+STM32F4+RGB565 TFT调试

热门文章

  1. 高质量生活必备的几个App
  2. 【abp项目发布到iis(初学者)】
  3. 每日学术速递2.17
  4. 【oracle数据库】控制台程序提示“池式连接请求超时”
  5. mysql——单行函数
  6. 75道逻辑思维题及答案(1-67答案)
  7. (附源码)php初中历史专题教学网站 毕业设计100623
  8. 基于VisualSFM的三维重建(一)
  9. 【软考中级】网络工程师怎么复习?
  10. Python中float() 函数是如何实现的?