json Schema 数据校验工具

JSON Schema官网

1:JSON Schema简介

学习json schema基础
和XML Schema用来验证xml数据结构一样,jsonSchema是验证JSONdata数据结构的强大工具。
如果不会写有自动生成工具:https://www.jsonschema.net/login

1.1:基础知识

在JSON模式中,空对象和true都是完全有效的模式,可以接受任何有效的JSON。

  • a.json文件
{ }          或者true

1.2:定义关键字解释

架构关键字:$schema and $id.
	$schema该关键字用于指定JSON Schema版本信息
	Id是唯一标识产品的数值。因为这是产品的规范标识符,所以它是必需的。
模式注释:title and description. 
	用来进行注释的,描述文件或者字段
验证关键字:type。
	定义数据的类型,定义后只支持该特定类型
属性关键字:properties
	定义该json的属性部分

demo

{
  "id":"this is json id .",
  "description":"this is test json schema .",
  "properties":{
    "name":{
      "type":"string",
      "description":"people name ."
    }
  }
}
1:$schema

用于指定版本信息:可在此查看schema版本
共有4;6;7等多个版本,比如6版本

"$schema": "http://json-schema.org/draft-06/schema#",

2:type支持数据类型

string
number
integer
object
array
boolean
null

2.1:string字符串

支持对字符串的长度,正则表达式。对于其他的一些格式,因为json中没有时间,ip等格式,统一为字符串,可以使用format关键字再进行定义。

定义字符串长度范围,值必须是非负数
{
  "type": "string",
  "minLength": 2,
  "maxLength": 3
}
  • 支持的参数
长度:minLength,maxLength
正则表达式 :pattern 
其他内置格式:对应使用format关键字:   "format":"",
	日期和时间:date-time;time;date;
	邮件地址:email;idn-email
	主机名:hostname
	IP:ipv4;ipv6
	资源标识符:uuid;uri 
	url模板:uri-template
	json指针:JSON Pointer
	正则表达式:regex
1:正则表达式

string支持正则表达式介绍。正则表达式规则介绍

.:匹配除换行符以外的任何字符。
^:仅在字符串的开头匹配。
$:仅在字符串末尾匹配。
(...):将一系列正则表达式组合成一个正则表达式。
|:匹配前面或后面的正则表达式|符号。
[abc]:匹配方括号内的任何字符。
[a-z]:匹配字符范围内的所有。
[^abc]:匹配字符以外的。
[^a-z]:匹配范围之外的任何字符。
+:匹配前面正则表达式的一个或多个重复。
*:匹配前面正则表达式的零个或多个重复。
?:匹配前面正则表达式的零个或一个重复。
+?,*?,??:该*,+,和?限定词都是贪婪的;它们匹配尽可能多的文本。有时这种行为是不可取的,您希望匹配尽可能少的字符。
(?!十),(?=x):消极和积极的前瞻。
{x}:完全匹配前面x位数正则表达式的出现。
{x,y}:至少匹配x最多y出现在前面位数的正则表达式。
{x,}:匹配x前面正则表达式的一次或多次出现。
{x}?,{x,y}?,{x,}?:上述表达式的懒惰版本。

demo:

{
   "type": "string",
   "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$",
}
//"(888)555-1212"   或者"555-1212"   都是符合的
// ^(([0-9]{3}))?  匹配0-9的数字匹配前3位,执行一次匹配或者0次
// [0-9]{3}			再匹配0-9的数子匹配3位,
// -[0-9]{4}$		-在数据末尾执行匹配0-9的数据匹配4位

2.2:数字类型

JSON模式中有两种数字类型:integer和number。它们共享相同的验证关键字。

  • integer:同于整数,不适用于小数点。
  • number:用于任何数值类型,整数或浮点数字。
    两者均可用于包括大写的一到十。

支持参数

倍数:multipleOf
范围:
	x ≥ minimum 
	x > exclusiveMinimum 
	x ≤ maximum
	x < exclusiveMaximum

2.3:object对象

对象是JSON中的映射类型。它们将“键”映射到“值”。在JSON中,“键”必须总是字符串。每一对通常被称为“property”。
{ “type”: “object” } :一个键值对也可以成为一个对象

object支持可选参数

{
  "type": "object",
  "properties": {},
  "patternProperties":{},
  "additionalProperties ":fasle或者true或者额外字段类型的定义,
 "required":[],
  "minProperties": 1,
  "maxProperties": 5
}
  • 1:properties
    properties 用于描述一个object对象的多个属性
{
  "type": "object",
  "properties": {
    "number": { "type": "number" }
  }
}

{ “number”: 1600}

  • 2:patternProperties
    对符合正则匹配的字段套用该定义
{
  "type": "object",
  "patternProperties": {
    "^S_": { "type": "string" },
    "^I_": { "type": "integer" }
  }
}

{ “S_25”: “This is a string” }

  • 3:additionalProperties 额外属性定义
{
  "type": "object",
  "properties": {
    "number": { "type": "number" },
  "additionalProperties": { "type": "string" }   //允许存在未被定义的字段,类型必须是字符串
  }
}

“additionalProperties”: false//不允许存在未被定义的字段
{ “number”: 1600, “street_name”: “Pennsylvania”} //属性未被定义

  • 4:required必需
    必需存在的属性
 {
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "email": { "type": "string" },
    "address": { "type": "string" },
    "telephone": { "type": "string" }
  },
  "required": ["name", "email"]
}

demo

{
  "name": "William Shakespeare",
  "email": "bill@stratford-upon-avon.co.uk"
}
  • 4 propertyNames 对属性名称规则正则匹配
  • 5 size
    定义每个对象中属性个数
"minProperties": 1,
"maxProperties": 5

2.4:数组

数组包括list和元组tuple 。可以定义枚举值,唯一值,最大值,最小值,元素个数等参数。

  • 1:array
    数组中可以使用items关键字定义每个值的类型
{
  "type": "array",
  "items": {   //定义每个元素类型
    "type": "number"
  },
   "uniqueItems": true   //是否允许值重复
   "minItems": 2,   	 //最小元素个数
   "maxItems": 3  		//最大元素个数
}
  • 2:tuple元组
 "prefixItems": 
 "items":
 "contains":{},
 "minContains": 2,
 "maxContains": 3
 "minItems": 2,
 "maxItems": 3

2.5:boolean

{ “type”: “boolean” } 允许的值为true或者false

2.6:架构组合

使用下面关键字进行组合不同定义的匹配,使得对于属性定义必须满足几个或者全部的要求,允许同时根据多个标准验证一个值一样简单。类似于AND、OR。

allOf  必须对所有子模式有效
anyOf 必须对任何子模式有效
oneOf 必须符合其中一个字schema
not 都不符合

所有这些关键字都必须设置为一个数组,其中每个项目都是一个模式

1:allOf 必须都符合

demo:类型必须是string并且要求最大长度

{
  "allOf": [
    { "type": "string" },
    { "maxLength": 5 }
  ]
}
2:anyOf 任何一个符合
3:oneOf 其中一个符合
4:not 都不符合

可以通过additionalProperties=false或者true进行不同模式间的共享或者关闭

2.7:处理xml或txt等json数据

可以对于是xml或者text等不符合json的数据定义默认的类型,比如

{  //定义该字符串中是一个txt或者xml
  "type": "string",
  "contentMediaType": "text/html"
}

2.8:条件属性绑定

对于某些字段间约束为一定的依赖关系,比如name属性必须依赖于age属性存在,其中一个不存在都不行。可以使用关键字

dependentRequired  
	同时存在或者同时不存在,可以定义双向依赖或者单向依赖
if/then/else
  • dependentRequired 定义了两个字段单向依赖
"dependentRequired": {
    "credit_card": ["billing_address"]
  }
  • if/then/else 对于子模式间的互相依赖判断,调用逻辑验证
    如果country值是“”然后。。。。。。
{
  "type": "object",
  "properties": {
    "street_address": {
      "type": "string"
    },
    "country": {
      "default": "United States of America",
      "enum": ["United States of America", "Canada"]
    }
  }, 
  ### 上面是定义,下面可以进行判断条用不同的校验
  "if": {
    "properties": { "country": { "const": "United States of America" } }
  },
  "then": {
    "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
  },
  "else": {
    "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
  }
}

2.9:结构复杂组合示例

allof+ 依赖组成的复杂schema定义
如果满足country字段定义然后执行,否则执行,相当于is-else操作。

{
 "allOf": [
    {
      "if": {
        "properties": { "country": { "const": "United States of America" } }
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{5}(-[0-9]{4})?" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Canada" } },
        "required": ["country"]
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]" } }
      }
    },
    {
      "if": {
        "properties": { "country": { "const": "Netherlands" } },
        "required": ["country"]
      },
      "then": {
        "properties": { "postal_code": { "pattern": "[0-9]{4} [A-Z]{2}" } }
      }
    }
  ]
}

2.10:type支持的通用参数

标题或者注释:title and description
字段默认值:"default": 
枚举值:enum :[]     //属性含有多个值
固定值:const:某属性的值为固定的一个值,值相等才校验通过
  比如: "id": {
              "type": "string",
              "const": "id"
            },

3:构造一个复杂的schema( r e f 和 ref和 refdef)

可以定义不同的schema,在定义相同的部分直接进行互相引用,但是在schema中没有类似URL的定位符,但是有$ref和$def关键字进行资源位置标识。简单来说就是复用,和代码复用一样。

1:$ref关键字

使用$ref关键字引用#/definitions/Ref字段的定义。#代表这个schema,/代表跟路径。

{
  "properties": {
    "prop": {
      "$ref" : "#/definitions/Ref"
    }
  },
  "definitions" : {
    "Ref" : {
      "type" : "number"
    }
  }
}

4:JSON Schema开发实战

JSON Schema java实战
Java-JSON-工具/JSON-模式验证器
开发校验器推荐:
使用Jackson来处理Java代码中的JSON,使用:Java-JSON-工具/JSON-模式验证器
使用org.json API那么使用:JSON Schema everit-java实战

  • 推荐在线json和json-schema校验工具:https://www.jsonschemavalidator.net/
  • 推荐json转换为json-schema工具:https://tooltt.com/json2schema/

4.1:everit-org验证器

如果使用org.json解析处理json数据,则适合用everit-org检验器API。

  • 1:检验器:SchemaLoader类
    使用该类作为总入口,获取验证器
  • 2:对于验证的冲突如何解决,或者说如何处理异常:提供了ValidationException.getCausingExceptions()获取每一个校验失败原因。
    获取每一个异常并打印
try {
  schema.validate(rectangleMultipleFailures);  //检验
} catch (ValidationException e) { 		 //获取异常
  System.out.println(e.getMessage());    //输出异常
  e.getCausingExceptions().stream()  	 //打印每个异常
      .map(ValidationException::getMessage)
      .forEach(System.out::println);
}
  • 3:json格式验证:为了清楚具体的json是否符合某种支持的类型,可以使用默认的校验器(ipv4等),也可以实现ValidationListener 接口验证数据。
    Validator validator = Validator.builder() .withListener(new YourValidationListenerImplementation()) .build(); validator.performValidation(schema, input);
  • 4:监听的严格程度:对于验证的失败数据是否继续验证可以进行设置
1:maven开发依赖
<dependency>
    <groupId>com.github.everit-org.json-schema</groupId>
    <artifactId>org.everit.json.schema</artifactId>
    <version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20201115</version>
 </dependency>

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

若上面依赖导入失败可用下方依赖,两者选用一个即可

<dependency>
            <groupId>com.networknt</groupId>
            <artifactId>json-schema-validator</artifactId>
            <version>1.0.63</version>
        </dependency>
        <dependency>
            <groupId>org.everit.json</groupId>
            <artifactId>org.everit.json.schema</artifactId>
            <version>1.5.1</version>
        </dependency
2:demo

json数据

{
  "name":"xiaoming",
  "age":99,
  "like":"baskball",
    "addr":{
      "city":"西安",
      "county":"chain"
    } 
}

schema规则

{
  "type": "object",
  "required": [],
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "number"
    },
    "like": {
      "type": "string"
    },
    "addr": {
      "type": "object",
      "required": [],
      "properties": {
        "city": {
          "type": "string"
        },
        "county": {
          "type": "string"
        }
      }
    }
  }
}

代码测试

 public static void main(String[] args) {
        /*加载schema文件*/
        InputStream jsonSchemaTest = jsonSchema.class.getClassLoader().getResourceAsStream("jsonSchemaTest.json");
        JSONObject jsonObject = new JSONObject(new JSONTokener(jsonSchemaTest));
        //将JSON schema的JSON加载到模式验证器实例中。
        Schema load = SchemaLoader.load(jsonObject);
        /*加载json文件*/
        InputStream jsonStream = jsonSchema.class.getClassLoader().getResourceAsStream("jsonSchema1Data.json");
//验证
        try {
            load.validate(new JSONObject(new JSONTokener(jsonStream)));
        } catch (ValidationException e) {
             e.getCausingExceptions();
            System.out.println("校验成功");
        }
    }

4.2:json-schema-validator校验器

1:maven依赖
<dependency>
    <groupId>com.github.java-json-tools</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>2.2.14</version>
</dependency>
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用 Java 语言编写程序来校验 JSON Schema 是非常容易的,可以使用许多库和框架来帮助您实现它。有许多第三方库和框架可以用于校验 JSON 格式,这些库和框架包括:Jackson,Gson,Genson,Apache Commons,Hibernate Validator,JsonSchemaJsonPath 和 FastJSON。 ### 回答2: 在Java中,可以使用现有的库来编写代码,使用jsonSchema校验数据。下面是使用Java编写的示例代码: 首先,需要导入相关的依赖库,例如使用Jackson库来处理JSON数据和使用json-schema-validator库来执行jsonSchema校验。可以通过Maven或Gradle等构建工具来管理依赖。 接下来,创建一个方法来执行校验操作。首先,需要定义jsonSchema的规则,可以使用JSON字符串或从外部文件中加载。然后,需要将待校验数据转换为JSON对象,可以使用Jackson库将字符串解析为JSON对象。 然后,使用json-schema-validator库中的JsonSchemaFactory类来创建JsonSchema实例。使用JsonSchema的validate方法对JSON数据进行校验,该方法会返回校验结果。 最后,根据校验结果进行相应的处理,可以输出校验失败的原因或执行其他操作。 以下是一个简单的示例代码: ```java import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonschema.core.exceptions.ProcessingException; import com.github.fge.jsonschema.core.report.ProcessingReport; import com.github.fge.jsonschema.main.JsonSchema; import com.github.fge.jsonschema.main.JsonSchemaFactory; public class JsonValidator { public static void main(String[] args) { String schema = "{ \"type\": \"object\", \"properties\": { \"name\": { \"type\": \"string\" } } }"; String data = "{ \"name\": \"John\" }"; boolean isValid = validateData(schema, data); if (isValid) { System.out.println("Data is valid."); } else { System.out.println("Data is invalid."); } } public static boolean validateData(String schemaString, String dataString) { ObjectMapper objectMapper = new ObjectMapper(); JsonNode schemaNode, dataNode; try { schemaNode = objectMapper.readTree(schemaString); dataNode = objectMapper.readTree(dataString); } catch (Exception e) { e.printStackTrace(); return false; } JsonSchemaFactory schemaFactory = JsonSchemaFactory.byDefault(); try { JsonSchema schema = schemaFactory.getJsonSchema(schemaNode); ProcessingReport report = schema.validate(dataNode); return report.isSuccess(); } catch (ProcessingException e) { e.printStackTrace(); return false; } } } ``` 以上代码使用了Jackson库将schema数据解析为JSON节点,然后使用json-schema-validator库来创建JsonSchema对象,并使用validate方法进行校验。最后根据校验结果输出相应的信息。 当运行以上代码时,如果数据满足schema的定义,会输出"Data is valid.",否则输出"Data is invalid."。这个示例中使用了简单的schema数据进行校验,实际使用中可以根据需要定义更复杂的schema,并使用更复杂的校验逻辑。 ### 回答3: 使用Java编写可以使用以下步骤来使用jsonSchema校验数据。 首先,你需要引入json-schema-validator库。你可以在Maven或Gradle中添加以下依赖项: 对于Maven: ```xml <dependency> <groupId>org.everit.json</groupId> <artifactId>org.everit.json.schema</artifactId> <version>1.12.1</version> </dependency> ``` 对于Gradle: ```groovy implementation 'org.everit.json:org.everit.json.schema:1.12.1' ``` 接下来,你需要创建一个json schema的字符串或从文件中读取json schema。假设你有以下的json schema字符串: ```json String schemaStr = "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"name\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"age\": {\n" + " \"type\": \"integer\"\n" + " }\n" + " },\n" + " \"required\": [\"name\", \"age\"]\n" + "}"; ``` 然后你可以使用下面的代码来校验数据: ```java import org.everit.json.schema.Schema; import org.everit.json.schema.ValidationException; import org.everit.json.schema.loader.SchemaLoader; import org.json.JSONObject; import org.json.JSONTokener; class Main { public static void main(String[] args) { String dataStr = "{\"name\":\"John\", \"age\":30}"; try { JSONObject jsonSchema = new JSONObject(new JSONTokener(schemaStr)); JSONObject jsonData = new JSONObject(new JSONTokener(dataStr)); Schema schema = SchemaLoader.load(jsonSchema); schema.validate(jsonData); System.out.println("数据是有效的"); } catch (ValidationException e) { System.out.println("数据无效:" + e.getMessage()); } } } ``` 以上代码将创建一个Schema对象,并使用Schema.validate方法来验证数据。如果数据有效,将输出“数据是有效的”,否则将输出"数据无效"及详细错误信息。 这就是使用Java编写jsonSchema校验数据的基本步骤。你可以根据自己的需求修改json schema数据,并在代码中进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值