JSON解析器之json schema校验及代码实现
Posted 童话_boy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSON解析器之json schema校验及代码实现相关的知识,希望对你有一定的参考价值。
项目有个业务需要对JSON格式的数据校验,需要一些必要字段的验证,实现一个JSON解析器。所以学习了json schema的语法和解析器的实现。
本篇是先说通用的JSON验证,也就是json schema和在java代码中的校验使用。
json schema是什么
json schema实际上就是一个JSON文件,文件内容是对JSON数据的结构及内容的约束,就像是xml文件的xsd文件对xml的验证。
先看一下简单的schema内容
1 { 2 "$schema": "http://json-schema.org/draft-07/schema#", 3 "title": "这是个标题", 4 "description": "校验模板内容json格式", 5 "type": "object", 6 "properties": { 7 "name": { "type": "string" }, 8 "credit_card": { "type": "number" }, 9 "job_arr": { 10 "type": "array", 11 "items": { 12 "type": "string" 13 } 14 }, 15 "billing_address": { 16 "type": "object", 17 "properties": { 18 "selfId": { 19 "type": "string" 20 } 21 } 22 } 23 }, 24 "dependencies": { 25 "credit_card": ["billing_address"] 26 }, 27 "required": ["name"] 28 }
json schema关键字
关键字 | 描述 |
---|---|
$schema | 表示该JSON Schema使用的版本规范,非必填,目前最新一版“Draft-07”是2019.09发布的。每个版本的语法可能有出入,方便以后人员维护建议使用 |
title | JSON Schema文件的标题,非必填 |
description | JSON Schema文件的描述信息,非必填 |
type | 待校验元素的类型(例如,最外层的type表示待校验的是一个JSON对象,内层type分别表示待校验的元素类型为,number,string,array,object) |
properties | JSON对象中,各个key-value对中value的限制条件 |
required | 校验的JSON对象中,必须存在的key,不存在则校验失败 |
typele类型常见的取值
string,object,array,integer(只能是int),number(float或者int),null,boolean
- string
maxLength: 校验string字符串的最大长度。超出长度校验失败。
minLength: 校验string字符串的最小长度。小于长度校验失败。
pattern: 字符串满足指定的正则表达式,才算通过校验。
format: 不常用,值只能是以下的取值date-time(时间格式)、email(邮件格式)、hostname(网站地址格式)、ipv4、ipv6、uri、uri-reference、uri-template、json-pointer。假如要校验的字符串是邮箱格式的可以使用"forma"t:"email",而不用pattern自己去指定正则表达式。
- object
properties: 每个key对应的值,都是一个json schema,则待校验JSON对象通过校验。从这里,我们可以看到,json schema的校验检测,这个对象才算是通过校验。
required: 值是个字符串数组,数组元素是本级的属性key。该关键字限制了JSON对象中必须包含哪些本级key。如果当然json不包含数组中的key则校验失败。
dependencies: 设置属性依赖,值是一个json schema。例如
"dependencies": {"credit_card":["billing_address"]},
表示有字段"credit_card"就必须有"billing_address"字段。但是这个依赖是单向的。有"billing_address"字段可以没有"credit_card"。
- array
items: 值是一个有效的JSON Schema或者一组有效的JSON Schema。只有待校验JSON数组中的所有元素均通过校验,整个数组才算通过校验。
例如:{"type": "array","items": { "type": "string", "minLength": 5 }} 这个数组只有满足长度大于5才会通过校验
uniqueItems: 值是一个布尔值,即boolean(true、false)。当该关键字的值为true时,只有待校验JSON数组中的所有元素都具有唯一性时,才能通过校验。
这里只是简单的列举了一些常用的关键字,如果想要学习更多的使用方法,可以去看下官方文档里面会有更详细的用例。
再分享两个链接
在程序中实现对json数据的校验
json schema官网中java语言对json schema的实现方式有三种
- everit-org/json-schema draft-07, -06, -04 (Apache License 2.0)
- Justify draft-07, -06, -04 (Apache License 2.0)
- networknt/json-schema-validator draft-07, -06, -04 Support OpenAPI 3.0 with Jackson parser (Apache License 2.0)
本篇介绍的是第三种---第三方工具feg
导入依赖fge包,因为fge的方法要用到jsonNode,所以也就需要导入jackson的包
1 <!-- fge --> 2 <dependency> 3 <groupId>com.github.fge</groupId> 4 <artifactId>json-schema-validator</artifactId> 5 <version>2.2.6</version> 6 </dependency> 7 <!-- fasterxml --> 8 <dependency> 9 <groupId>com.fasterxml.jackson.core</groupId> 10 <artifactId>jackson-core</artifactId> 11 <version>2.3.0</version> 12 </dependency> 13 <dependency> 14 <groupId>com.fasterxml.jackson.core</groupId> 15 <artifactId>jackson-databind</artifactId> 16 <version>2.3.0</version> 17 </dependency>
将JSON数据转成jsonNode:
1 /** 2 * @param jsonStr 验证json字符串 3 */ 4 private static JsonNode strToJsonNode(String jsonStr) { 5 JsonNode jsonNode = null; 6 try { 7 jsonNode = JsonLoader.fromString(jsonStr); 8 } catch (IOException e) { 9 e.printStackTrace(); 10 } 11 return jsonNode; 12 }
获取本地的josn schema文件:
基于springboot项目,schema.json约束文件放在了resources/static/ 文件夹下
String jsonFilePath = "classpath:static/schema.json";
通过spring的工具类ResourceUtils.getFile(jsonFilePath)获取到文件的绝对路径
使用classpath:方法的好处就是不用在代码中写绝对路径。部署项目时不需要关心文件的位置。只要项目中的static文件中有schema.json文件就能获取到
1 /** 2 * @param jsonFilePath jsonSchema文件路径 3 */ 4 private static JsonNode schemaToJsonNode(String jsonFilePath) { 5 JsonNode jsonSchemaNode=null; 6 try { 7 jsonSchemaNode= new JsonNodeReader().fromReader(new FileReader(ResourceUtils.getFile(jsonFilePath))); 8 } catch (IOException e) { 9 e.printStackTrace(); 10 } 11 return jsonSchemaNode; 12 }
schema校验代码实例:
1 /** 2 * @param jsonNode json数据node 3 * @param schemaNode jsonSchema约束node 4 */ 5 private static boolean getProcessingReport(JsonNode jsonNode, JsonNode schemaNode) { 6 //fge验证json数据是否符合json schema约束规则 7 ProcessingReport report = JsonSchemaFactory.byDefault().getValidator().validateUnchecked(schemaNode, jsonNode); 8 if (report.isSuccess()) { 9 // 校验成功 10 return true; 11 } else { 12 Iterator<ProcessingMessage> it = report.iterator(); 13 StringBuilder ms = new StringBuilder(); 14 ms.append("json格式错误: "); 15 while (it.hasNext()) { 16 ProcessingMessage pm = it.next(); 17 if (!LogLevel.WARNING.equals(pm.getLogLevel())) { 18 ms.append(pm); 19 } 20 } 21 System.err.println(ms); 22 return false; 23 } 24 }
写在最后
本篇文章只为了记录和分享自己学习的成果,能够帮助更多的小伙伴当然是更好了,如果有错误欢迎指出。谢谢!
以上是关于JSON解析器之json schema校验及代码实现的主要内容,如果未能解决你的问题,请参考以下文章