• JsonSchema学习笔记


    一、什么是JsonSchema?

    JsonSchema本质是一套规则,用来定义Json的数据格式。
    例如定义人员信息,包含名字、年龄、生日。需要对这个人员信息的格式有约定,名字必须是字符串,年龄必须是整数,生日必须是日期类型的字符串。举例一个Json数据

    {
        "name":"shoulinniao",
        "age":24,
        "birthday":"1998-11-11"
    }
    

    想要校验人员信息的JsonSchema可以是这么一个Json格式的规则

    {
        "type":"object",
        "properties":{
            "name":{
                "type":"string"
            },
            "age":{
                "type":"integer"
            },
            "birthday":{
                "type":"string",
                "format":"date"
            }
        }
    }
    

    在线生成JsonSchema的工具:https://www.jsonschema.net/home
    在线校验JsonSchema的工具:https://jsonschemalint.com/#!/version/draft-07/markup/json
    JsonSchema版本有3个,draft-04、draft-06、draft-07
    版本声明关键字$schema

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

    二、类型关键字

    定义一种数据结构首先从数据类型出发,例如学Java之初的八种基本数据类型。JsonSchema作为一套成熟的规则,也有自己的类型定义描述。
    从上面的例子可以很容易看到"type"是定义类型的关键字,类型可以是"object","string","integer"。具体的数据类型有以下几种

    1. object 对象,可以包含多个字段
    2. string 字符串
    3. number 数字,包括浮点数和消暑
    4. integer 整数
    5. array 数组
    6. boolean 布尔,只有true和false两个合法值
    7. null 空,只有null一个合法值

    三、类型额外特定参数

    1.字符串string

    • minLength:最小长度
    • maxLength:最大长度
    • pattern:正则表达式
    • format:字符串格式,内容可以是date、time、data-time、email、hostname等
       {
           "type":"string",
           "minLength":11,
           "maxLength":100,
           "pattern":"^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$",
           "format":"date"
       }
      

    2. 数值number和integer参数都相同

    • 满足某个数的倍数:multipleOf
    • 最小值:minimum
    • 最大值:maximum
    • 开区间最小值:exclusiveMinimum
    • 开区间最大值:exclusiveMaximum
    {
        "type":"number",
        "multipleOf":5,
        "minimum":66,
        "maximum":99,
        "exclusiveMinimum":1234,
        "exclusiveMaximum":8888
    }
    

    这里显然区间最值与最大最小值矛盾,但这是合法的JsonSchema。
    注意:这个例子如果用draft-04则会报错,其他两个版本则校验正常。

    3. 布尔boolean和空值null类型没有额外的类型特定参数

    4. 数组array

    • items:成员类型,对应值可以是一个JsonSchema,规定数组元素的JsonSchema,也可以是一个JsonSchema数组,要求数组元素按照JsonSchema数组的要求一一对应。
    • additionalItems:true/false,是否允许额外成员类型,仅当items是数组Schema才起作用,额外元素追加在数组后面。
    • minItems:数组元素最小个数
    • maxItems:数组元素最大个数
    • uniqueItems:true/false,数组元素是否唯一
    • contains:数组元素必须满足的schema样式
    • minContains:数组必须满足contains样式的最少元素个数
    • maxContains:数组必须满足contains样式的最多元素个数

    例如以下Schema,定义了第一个元素必须是数值,第二个元素必须是字符串,允许追加其他元素在第二个元素后,并且元素个数必须大于等于2,小于等于54,元素值必须唯一的数组类型。

    {
        "type":"array",
        "items":[
            {
                "type":"number"
            },
            {
                "type":"string"
            }
        ],
        "additionalItems":true,
        "minItems":2,
        "maxItems":54,
        "uniqueItems":true
       }
    

    举例合适的Json数组 [1998,"shoulinniao",true]

    5. 对象object

    最常用的类型,Json格式一层套一层

    • properties:成员的schema,json格式,key是对象字段名,value是又一个schema
    • patternProperties:批量定义成员的schema,正则匹配多个key对应一种schema
    • required:必须出现的成员,数组格式
    • dependencies:成员依赖关系,json格式,key是字符串,value是字符串数组,表示key属性出现value数组里的所有属性不能缺席
    • additionalProperties:true/false,是否允许出现properties中没有定义的属性
    • minProperties:最少属性个数
    • maxProperties:最多属性个数

    例如开头举例的人员信息可以用以下schema校验

    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "birthday": {
          "type": "string",
          "format": "date"
        }
      },
      "required": [
        "name"
      ],
      "dependencies": {
        "name": [
          "age",
          "birthday"
        ]
      }
    }
    

    四、逻辑组合

    • allOf:满足数组里所有的schema,数组格式
    • anyOf:满足任意多个schema,数组格式
    • oneOf:必须满足且仅满足其中一个schema,数组格式
    • not:不能满足not对应的schema,json格式

    五、复杂结构

    • 定义:没有固定关键字,习惯在根节点的"definations"下定义可以多次引用的schema
    • $id:唯一标识定义中的属性,可以通过id引用,而不需要根节点下的完整路径
    • $ref:引用,路径以#开头代表根节点或者ID

    schema和数据举例

    {
      "definitions": {
        "bbox": {
          "$id": "bbox_schema",
          "type": "array",
          "item": {
            "type": "number"
          },
          "minLength": 4,
          "maxLength": 4
        }
      },
      "type": "object",
      "properties": {
        "plate_bbox": {
          "$ref": "#/definitions/bbox"
        },
        "table_bbox": {
          "$ref": "bbox_schema"
        }
      }
    }
    {
      "plate_bbox": [3,4,5,6],
      "table_bbox": [7,7,3,4]
    }
    

    六、通用关键字

    enum:枚举数组,值必须选择其中一个,数组格式。
    以下的仅用于描述,不影响校验效果

    • title:标题
    • description:描述
    • default:默认值
    • example:举例说明
    • "$comment":批注

    七、Java代码运用

    1.导入依赖包

    <dependency>
    	<groupId>com.github.erosb</groupId>
    	<artifactId>everit-json-schema</artifactId>
    	<version>1.14.0</version>
    </dependency>
    

    2.校验

            public static void main (String[]args){
                String json = "{\"plate_bbox\":[3,4,5,6],\"table_bbox\":[7,7,3,4]}";
                JSONObject jsonObject = new JSONObject(json);
                String jsonSchema = "{\"definitions\":{\"bbox\":{\"$id\":\"bbox_schema\",\"type\":\"array\",\"item\":{\"type\":\"number\"},\"minLength\":4,\"maxLength\":4}},\"type\":\"object\",\"properties\":{\"plate_bbox\":{\"$ref\":\"#/definitions/bbox\"},\"table_bbox\":{\"$ref\":\"bbox_schema\"}}}";
                JSONObject jsonSchemaObject = new JSONObject(jsonSchema);
                //两种方法确定版本
                // 1、在JsonSchema里把版本定义好了,否则默认加载4版本,如果加载6、7版本的特定内容会失败
                Schema schema = SchemaLoader.load(jsonSchemaObject);
                // 2、没有在JsonSchema里定义版本,声明加载器的版本
                SchemaLoader schemaLoader = SchemaLoader.builder().schemaJson(jsonSchemaObject).draftV7Support().build();
                schema = schemaLoader.load().build();
                // 校验
                schema.validate(jsonObject);
            }
    
  • 相关阅读:
    spring boot 配置示例
    MyBatis 常用标签用法
    http请求头部常用参数
    CentOS7使用firewalld打开关闭防火墙与端口
    java8 base64
    MD5工具类
    各种远程登录工具
    MySql 常用命令
    spring-boot-mybaits 开启事务
    springboot 项目打包到 linux下无法 运行
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/15962301.html
Copyright © 2020-2023  润新知