JSON Schema入門

JsonSchema官方文檔
入門文檔
入門文檔
生成Schema工具

使用Json的好處(什么是Schema):

  • 描述現(xiàn)有的數(shù)據(jù)格式
  • 提供清晰的人工和機(jī)器可讀文檔
  • 完整的數(shù)據(jù)結(jié)構(gòu),有利于自動(dòng)化測(cè)試
  • 完整的數(shù)據(jù)結(jié)構(gòu),有利于驗(yàn)證客戶端提交數(shù)據(jù)的質(zhì)量

什么是JSON Schema

  • JSON Schema本身就是一種數(shù)據(jù)結(jié)構(gòu),可以清晰的描述JSON數(shù)據(jù)的結(jié)構(gòu)。是一種描述JSON數(shù)據(jù)的JSON數(shù)據(jù)。

使用JSON Schema的好處

  • JSON Schema 非常適用于基于JSON的HTTP的API。
  • JSON Schema從Java的基本數(shù)據(jù)類型中對(duì)JSON結(jié)構(gòu)進(jìn)行校驗(yàn),所以對(duì)JSON結(jié)構(gòu)的校驗(yàn)可以理解為對(duì)每種不同數(shù)據(jù)類型的相應(yīng)校驗(yàn)。
  • 接口測(cè)試中可以快速的定位到自己數(shù)據(jù)格式的正確性。

JSON模式示例

{
    "$schema":"http://json-schema.org/draft-04/schema#",
    "title":"book info",
    "description":"some information about book",
    "type":"object",
    "properties":{
        "id":{
            "description":"The unique identifier for a book",
            "type":"integer",
            "minimum":1
        },
        "name":{
            "type":"string",
            "pattern":"^#([0-9a-fA-F]{6}$",
            "maxLength":6,
            "minLength":6
        },
        "price":{
            "type":"number",
            "multipleOf":0.5,
            "maximum":12.5,
            "exclusiveMaximum":true,
            "minimum":2.5,
            "exclusiveMinimum":true
        },
        "tags":{
            "type":"array",
            "items":[
                {
                    "type":"string",
                    "minLength":5
                },
                {
                    "type":"number",
                    "minimum":10
                }
            ],
            "additionalItems":{
                "type":"string",
                "minLength":2
            },
            "minItems":1,
            "maxItems":5,
            "uniqueItems":true
        }
    },
    "minProperties":1,
    "maxProperties":5,
    "required":[
        "id",
        "name",
        "price"
    ]
}

關(guān)鍵字說明

JOSN模式中常用的關(guān)鍵字(加粗字體為常用字段)

關(guān)鍵字 描述
$schema The $schema 關(guān)鍵字狀態(tài),這種模式被寫入草案V4規(guī)范。
title 將使用此架構(gòu)提供一個(gè)標(biāo)題,title一般用來進(jìn)行簡(jiǎn)單的描述,可以省略
description 架構(gòu)的一點(diǎn)描述,description一般是進(jìn)行詳細(xì)的描述信息,可以省略
type 用于約束校驗(yàn)的JSON元素的數(shù)據(jù)類型,是JSON數(shù)據(jù)類型關(guān)鍵字定義的第一個(gè)約束條件:它必須是一個(gè)JSON對(duì)象
properties 定義屬性:定義各個(gè)鍵和它們的值類型,最小和最大值中要使用JSON文件
required 必需屬性,這個(gè)關(guān)鍵字是數(shù)組,數(shù)組中的元素必須是字符串
minimum 這是約束的值,并代表可接受的最小值
exclusiveMinimum 如果“exclusiveMinimum”的存在,并且具有布爾值true的實(shí)例是有效的,如果它是嚴(yán)格的最低限度的值
maximum 這是約束的值被提上表示可接受的最大值
exclusiveMaximum 如果“exclusiveMaximum”的存在,并且具有布爾值true的實(shí)例是有效的,如果它是嚴(yán)格的值小于“最大”。
multipleOf 數(shù)值實(shí)例有效反對(duì)“multipleOf”分工的實(shí)例此關(guān)鍵字的值,如果結(jié)果是一個(gè)整數(shù)。
maxLength 字符串實(shí)例的長(zhǎng)度被定義為字符的最大數(shù)目
minLength 字符串實(shí)例的長(zhǎng)度被定義為字符的最小數(shù)目
pattern String實(shí)例被認(rèn)為是有效的,如果正則表達(dá)式匹配成功實(shí)例

聲明JSON模式

由于JSON Schema本身就是JSON,所以當(dāng)一些東西是JSON Schema或者只是JSON的任意一塊時(shí),并不總是很容易分辨。該 schema關(guān)鍵字用于聲明某些內(nèi)容是JSON Schema,schema設(shè)置schema所使用的參照標(biāo)準(zhǔn)。包含它通常是一種很好的做法,盡管不是必需的。

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

聲明唯一標(biāo)識(shí)符(不懂)

最佳做法是將$id屬性包含為每個(gè)模式的唯一標(biāo)識(shí)符。現(xiàn)在,只需將其設(shè)置為您控制的域中的URL,例如:

{ "$id": "http://yourdomain.com/schemas/myschema.json"}

type常見取值

Type其實(shí)就是JSON數(shù)據(jù)的基本數(shù)據(jù)類型,一般是有6種,加上null一共有7種:

type取值 對(duì)應(yīng)的Java數(shù)據(jù)類型
object java.lang.Object
array java.util.List
integer int(java.lang.Integer)
number float(java.lang.Float)或int
null null
boolean java.lang.Boolean
string java.lang.String

type:Object

示例:

{
    "type":"object",
    "properties":{
        "id":{
            "description":"The unique identifier for a book",
            "type":"integer",
            "minimum":1
        },
        "price":{
            "type":"number",
            "minimum":0,
            "exclusiveMinimum":true
        }
    },
    "patternProperties":{
        "^a":{
            "type":"number"
        },
        "^b":{
            "type":"string"
        }
    },
    "additionalProperties":{
        "type":"number"
    },
    "minProperties":1,
    "maxProperties":5,
    "required":[
        "id",
        "name",
        "price"
    ]
}

object類型有三個(gè)關(guān)鍵字:type(限定類型),properties(定義object的各個(gè)字段),required(限定必需字段)

關(guān)鍵字 描述
type 類型
properties 定義屬性
required 必須屬性
maxProperties 最大屬性個(gè)數(shù)
minProperties 最小屬性個(gè)數(shù)
additionalProperties 如果待校驗(yàn)JSON對(duì)象中存在,既沒有在properties中被定義,又沒有在patternProperties中被定義,那么這些一級(jí)key必須通過additionalProperties的校驗(yàn)。true or false or object 參考
minProperties、maxProperties說明(用的不是很多)

這兩個(gè)關(guān)鍵字的值都是非負(fù)整數(shù)。待校驗(yàn)的JSON對(duì)象中一級(jí)key的個(gè)數(shù)限制,minProperties指定了待校驗(yàn)的JSON對(duì)象可以接受的最少一級(jí)key的個(gè)數(shù),maxProperties指定了待校驗(yàn)JSON對(duì)象可以接受的最多一級(jí)key的個(gè)數(shù)

patternProperties

正則表達(dá)式匹配json出現(xiàn)的屬性,該JSON對(duì)象的每一個(gè)一級(jí)key都是一個(gè)正則表達(dá)式,用來匹配value值。

只有待校驗(yàn)JSON對(duì)象中的一級(jí)key,通過與之匹配的patternProperties中的一級(jí)正則表達(dá)式,對(duì)應(yīng)的JSON Schema的校驗(yàn),才算通過校驗(yàn)。例如,如果patternProperties對(duì)應(yīng)的值如下:

在待校驗(yàn)JSON對(duì)象中,所有以S開頭的key的value都必須是number,所有以I開頭的一級(jí)key的value都必須是string。

{
    "patternProperties": {
        "^S_": {
            "type": "number"
        },
        "^I": {
            "type": "string"
        }
    }
}

type:array

示例:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    {
    "type":"array",
    "items":[
        {
            "type":"string",
            "minLength":5
        },
        {
            "type":"number",
            "minimum":10
        }
    ],
    "additionalItems":{
        "type":"string",
        "minLength":2
    },
    "minItems":1,
    "maxItems":5,
    "uniqueItems":true
}

array有三個(gè)單獨(dú)的屬性:items,minItems,uniqueItems:

關(guān)鍵字 描述
items array 每個(gè)元素的類型
minItems 約束屬性,數(shù)組最小的元素個(gè)數(shù)
maxItems 約束屬性,數(shù)組最大的元素個(gè)數(shù)
uniqueItems 約束屬性,每個(gè)元素都不相同
additionalProperties 約束items的類型,不建議使用 示例
Dependencies 屬性依賴 用法
patternProperties 用法
items

該關(guān)鍵字的值是一個(gè)有效的JSON Schema或者一組有效的JSON Schema。

{
   "type": "array",
   "items": {
     "type": "string",
     "minLength": 5 
   }
}

上面的JSON Schema的意思是,待校驗(yàn)JSON數(shù)組的元素都是string類型,且最小可接受長(zhǎng)度是5。那么下面這個(gè)JSON數(shù)組明顯是符合要求的,具體內(nèi)容如下:
["myhome", "green"]
下面這個(gè)JSON數(shù)組明顯不符合要求
["home", "green"]

當(dāng)該關(guān)鍵字的值是一組有效的JSON Schema時(shí),只有待校驗(yàn)JSON數(shù)組的所有元素通過items的值中對(duì)應(yīng)位置上的JSON Schema的校驗(yàn),那么,整個(gè)待校驗(yàn)JSON數(shù)組才算通過校驗(yàn)。

這里需要注意的是:如果items定義的有效的JSON Schema的數(shù)量和待校驗(yàn)JSON數(shù)組中元素的數(shù)量不一致,那么就要采用“取小原則”。
即,如果items定義了3個(gè)JSON Schema,但是待校驗(yàn)JSON數(shù)組只有2個(gè)元素,這時(shí),只要待校驗(yàn)JSON數(shù)組的前兩個(gè)元素能夠分別通過items中的前兩個(gè)JSON Schema的校驗(yàn),那么,我們認(rèn)為待校驗(yàn)JSON數(shù)組通過了校驗(yàn)。而,如果待校驗(yàn)JSON數(shù)組有4個(gè)元素,這時(shí),只要待校驗(yàn)JSON數(shù)組的前三個(gè)元素能夠通過items中對(duì)應(yīng)的JSON Schema的校驗(yàn),我們就認(rèn)為待校驗(yàn)JSON數(shù)組通過了校驗(yàn)。
例如,如果items的值如下:

{
    "type":"array",
    "items":[
        {
            "type":"string",
            "minLength":5
        },
        {
            "type":"number",
            "minimum":10
        },
        {
            "type":"string"
        }
    ]
}

上面的JSON Schema指出了待校驗(yàn)JSON數(shù)組應(yīng)該滿足的條件,數(shù)組的第一個(gè)元素是string類型,且最小可接受長(zhǎng)度為5,數(shù)組的第二個(gè)元素是number類型,最小可接受的值為10,數(shù)組的第三個(gè)元素是string類型。那么下面這兩個(gè)JSON數(shù)組明顯是符合要求的,具體內(nèi)容如下:
["green", 10, "good"]
["helloworld", 11]
下面這兩個(gè)JSON數(shù)組卻是不符合要求的,具體內(nèi)容如下:
["green", 9, "good"]//9小于minimum
["good", 12]//good小于minLength

additionalItems

該關(guān)鍵字的值是一個(gè)有效的JSON Schema。

需要注意的是,該關(guān)鍵字只有在items關(guān)鍵字的值為一組有效的JSON Schema的時(shí)候,才可以使用,用于規(guī)定超出items中JSON Schema總數(shù)量之外的待校驗(yàn)JSON數(shù)組中的剩余的元素應(yīng)該滿足的校驗(yàn)邏輯。只有這些剩余的所有元素都滿足additionalItems的要求時(shí),待校驗(yàn)JSON數(shù)組才算通過校驗(yàn)。

可以這么理解,當(dāng)items的值為一組有效的JOSN Schema的時(shí)候,一般可以和additionalItems關(guān)鍵字組合使用,items用于規(guī)定對(duì)應(yīng)位置上應(yīng)該滿足的校驗(yàn)邏輯,而additionalItems用于規(guī)定超出items校驗(yàn)范圍的所有剩余元素應(yīng)該滿足的條件。如果二者同時(shí)存在,那么只有待校驗(yàn)JSON數(shù)組同時(shí)通過二者的校驗(yàn),才算真正地通過校驗(yàn)。

另外,需要注意的是,如果items只是一個(gè)有效的JSON Schema,那么就不能使用additionalItems,原因也很簡(jiǎn)單,因?yàn)閕tems為一個(gè)有效的JSON Schema的時(shí)候,其規(guī)定了待校驗(yàn)JSON數(shù)組所有元素應(yīng)該滿足的校驗(yàn)邏輯。additionalItems已經(jīng)沒有用武之地了。

強(qiáng)調(diào)一下,省略該關(guān)鍵字和該關(guān)鍵字的值為空J(rèn)SON Schema,具有相同效果。

{
    "type": "array",
    "items": [
        {
            "type": "string",
            "minLength": 5
        },
        {
            "type": "number",
            "minimum": 10
        }
    ],
    "additionalItems": {
        "type": "string",
        "minLength": 2
    }
}

上面的JSON Schema的意思是,待校驗(yàn)JSON數(shù)組第一個(gè)元素是string類型,且可接受的最短長(zhǎng)度為5個(gè)字符,第二個(gè)元素是number類型,且可接受的最小值為10,剩余的其他元素是string類型,且可接受的最短長(zhǎng)度為2。
那么,下面三個(gè)JSON數(shù)組是能夠通過校驗(yàn)的,具體內(nèi)容如下:
["green", 10, "good"]
["green", 11]
["green", 10, "good", "ok"]
下面JSON數(shù)組是無法通過校驗(yàn)的,具體內(nèi)容如下:
["green", 10, "a"]
["green", 10, "ok", 2]

minItems、maxItems

這兩個(gè)關(guān)鍵字的值都是非負(fù)整數(shù)。

指定了待校驗(yàn)JSON數(shù)組中元素的個(gè)數(shù)限制,minItems指定了待校驗(yàn)JSON數(shù)組可以接受的最少元素個(gè)數(shù),而maxItems指定了待校驗(yàn)JSON數(shù)組可以接受的最多元素個(gè)數(shù)。

另外,需要注意的是,省略minItems關(guān)鍵字和該關(guān)鍵字的值為0,具有相同效果。而,如果省略maxItems關(guān)鍵字則表示對(duì)元素的最大個(gè)數(shù)沒有限制。
例如,如果限制一個(gè)JSON數(shù)組的元素的最大個(gè)數(shù)為5,最小個(gè)數(shù)為1,則JSON Schema如下:
"minItems": 1,"maxItems": 5

uniqueItems

該關(guān)鍵字的值是一個(gè)布爾值,即boolean(true、false)。

當(dāng)該關(guān)鍵字的值為true時(shí),只有待校驗(yàn)JSON數(shù)組中的所有元素都具有唯一性時(shí),才能通過校驗(yàn)。當(dāng)該關(guān)鍵字的值為false時(shí),任何待校驗(yàn)JSON數(shù)組都能通過校驗(yàn)。

另外,需要注意的是,省略該關(guān)鍵字和該關(guān)鍵字的值為false時(shí),具有相同的效果。例如:
"uniqueItems": true

contains

注意:該關(guān)鍵字,官方說明中支持,但是,有可能你使用的平臺(tái)或者第三方工具不支持。所以,使用需謹(jǐn)慎。

該關(guān)鍵字的值是一個(gè)有效的JSON Schema。

只有待校驗(yàn)JSON數(shù)組中至少有一個(gè)元素能夠通過該關(guān)鍵字指定的JSON Schema的校驗(yàn),整個(gè)數(shù)組才算通過校驗(yàn)。

另外,需要注意的是,省略該關(guān)鍵字和該關(guān)鍵字的值為空J(rèn)SON Schema具有相同效果。


type:string

示例

{
    "$schema":"http://json-schema.org/draft-04/schema#",
    "title":"Product",
    "description":"A product from Acme's catalog",
    "type":"object",
    "properties":{
        "ip":{
            "type":"string",
            "pattern":"w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*"
        },
        "host":{
            "type":"phoneNumber",
            "pattern":"((d{3,4})|d{3,4}-)?d{7,8}(-d{3})*"
        },
        "email":{
            "type":"string",
            "format":"email"
        }
    },
    "required":[
        "ip",
        "host"
    ]
}
關(guān)鍵字 描述
maxLength 定義字符串的最大長(zhǎng)度,>=0
minLength 定義字符串的最小長(zhǎng)度,>=0
pattern 用正則表達(dá)式約束字符串,只有待校驗(yàn)JSON元素符合該關(guān)鍵字指定的正則表達(dá)式,才算通過校驗(yàn)
format 字符串的格式

format該關(guān)鍵字的值只能是以下取值:date-time(時(shí)間格式)、email(郵件格式)、hostname(網(wǎng)站地址格式)、ipv4、ipv6、uri、uri-reference、uri-template、json-pointer。
如果待校驗(yàn)的JSON元素正好是一個(gè)郵箱地址,那么,我們就可以使用format關(guān)鍵字進(jìn)行校驗(yàn),而不必通過pattern關(guān)鍵字指定復(fù)雜的正則表達(dá)式進(jìn)行校驗(yàn)。


type:integer or number

示例

{
    "$schema":"http://json-schema.org/draft-04/schema#",
    "title":"Product",
    "description":"A product from Acme's catalog",
    "type":"object",
    "properties":{
        "price":{
            "type":"number",
            "multipleOf":0.5,
            "maximum":12.5,
            "exclusiveMaximum":true,
            "minimum":2.5,
            "exclusiveMinimum":true
        }
    },
    "required":[
        "price"
    ]
}

integer和number的區(qū)別,integer相當(dāng)于Java中的int類型,而number相當(dāng)于Java中的int或float類型。
number 關(guān)鍵字可以描述任意長(zhǎng)度,任意小數(shù)點(diǎn)的數(shù)字。

關(guān)鍵字 描述
minimum 最小值
exclusiveMinimum 如果存在 "exclusiveMinimum" 并且具有布爾值 true,如果它嚴(yán)格意義上大于 "minimum" 的值則實(shí)例有效。
maximum 約束屬性,最大值
exclusiveMaximum 如果存在 "exclusiveMinimum" 并且具有布爾值 true,如果它嚴(yán)格意義上小于 "maximum" 的值則實(shí)例有效。
multipleOf 是某數(shù)的倍數(shù),必須大于0的整數(shù)
multipleOf

該關(guān)鍵字的值是一個(gè)大于0的number,即可以是大于0的int,也可以是大于0的float。
只有待校驗(yàn)的值能夠被該關(guān)鍵字的值整除,才算通過校驗(yàn)。
如果含有該關(guān)鍵字的JSON Schema如下
{ "type": "integer", "multipleOf": 2 }
2、4、6都是可以通過校驗(yàn)的,但是,3、5、7都是無法通過校驗(yàn)的,當(dāng)然了,2.0、4.0也是無法通過校驗(yàn)的,但是,并不是因?yàn)閙ultipleOf關(guān)鍵字,而是因?yàn)閠ype關(guān)鍵字。
如果含有multipleOf關(guān)鍵字的JSON Schema如下
{ "type": "number", "multipleOf": 2.0 }
2、2.0、4、4.0都是可以通過校驗(yàn)的,但是,3、3.0、3、3.0都是無法通過校驗(yàn)的。
另外,需要注意的是,省略該關(guān)鍵字則不對(duì)待校驗(yàn)數(shù)值進(jìn)行該項(xiàng)校驗(yàn)。

maximum

該關(guān)鍵字的值是一個(gè)number,即可以是int,也可以是float。
該關(guān)鍵字規(guī)定了待校驗(yàn)元素可以通過校驗(yàn)的最大值。
省略該關(guān)鍵字,即表示對(duì)待校驗(yàn)元素的最大值沒有要求

exclusiveMaximum

該關(guān)鍵字的值是一個(gè)boolean。
該關(guān)鍵字通常和maximum一起使用,當(dāng)該關(guān)鍵字的值為true時(shí),表示待校驗(yàn)元素必須小于maximum指定的值;當(dāng)該關(guān)鍵字的值為false時(shí),表示待校驗(yàn)元素可以小于或者等于maximum指定的值。
需要注意的是,省略該關(guān)鍵字和該關(guān)鍵字的值為false,具有相同效果。例如:
{ "type": "number", "maximum": 12.3, "exclusiveMaximum": true }

minimum、exclusiveMinimum

minimum、exclusiveMinimum關(guān)鍵字的用法和含義與maximum、exclusiveMaximum相似。唯一的區(qū)別在于,一個(gè)約束了待校驗(yàn)元素的最小值,一個(gè)約束了待校驗(yàn)元素的最大值。


type:boolean

對(duì)應(yīng)著true或者false

{
    "type":"object",
    "properties":{
        "number":{
            "type":"boolean"
        }
    }
}

進(jìn)階

type:enum

該關(guān)鍵字的值是一個(gè)數(shù)組,該數(shù)組至少要有一個(gè)元素,且數(shù)組內(nèi)的每一個(gè)元素都是唯一的。

如果待校驗(yàn)的JSON元素和數(shù)組中的某一個(gè)元素相同,則通過校驗(yàn)。否則,無法通過校驗(yàn)。

注意,該數(shù)組中的元素值可以是任何值,包括null。省略該關(guān)鍵字則表示無須對(duì)待校驗(yàn)元素進(jìn)行該項(xiàng)校驗(yàn)。

{
    "type":"object",
    "properties":{
        "street_type":{
            "type":"string",
            "enum":[
                "Street",
                "Avenue",
                "Boulevard"
            ]
        }
    }
}
{
    "type":"object",
    "properties":{
        "street_type":[
            "Street",
            "Avenue",
            "Boulevard"
        ]
    }
}
type:const

該關(guān)鍵字的值可以是任何值,包括null。
如果待校驗(yàn)的JSON元素的值和該關(guān)鍵字指定的值相同,則通過校驗(yàn)。否則,無法通過校驗(yàn)。
省略該關(guān)鍵字則表示無須對(duì)待校驗(yàn)元素進(jìn)行該項(xiàng)校驗(yàn)。
注意,該關(guān)鍵字部分第三方工具,并不支持

關(guān)鍵字:$ref

用來引用其他的schema
示例:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product set",
    "type": "array",
    "items": {
        "title": "Product",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
            },
            "dimensions": {
                "type": "object",
                "properties": {
                    "length": {"type": "number"},
                    "width": {"type": "number"},
                    "height": {"type": "number"}
                },
                "required": ["length", "width", "height"]
            },
            "warehouseLocation": {
                "description": "Coordinates of the warehouse with the product",
                "$ref": "http://json-schema.org/geo"
            }
        },
        "required": ["id", "name", "price"]
    }
}
關(guān)鍵字definitions

當(dāng)一個(gè)schema寫的很大的時(shí)候,可能需要?jiǎng)?chuàng)建內(nèi)部結(jié)構(gòu)體,再使用$ref進(jìn)行引用,示列如下:

{
    "type": "array",
    "items": { "$ref": "#/definitions/positiveInteger" },
    "definitions": {
        "positiveInteger": {
            "type": "integer",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    }
}
關(guān)鍵字:allOf

該關(guān)鍵字的值是一個(gè)非空數(shù)組,數(shù)組里面的每個(gè)元素都必須是一個(gè)有效的JSON Schema。
只有待校驗(yàn)JSON元素通過數(shù)組中所有的JSON Schema校驗(yàn),才算真正通過校驗(yàn)。
意思是展示全部屬性,建議用requires替代,不建議使用,示例如下

{
    "definitions":{
        "address":{
            "type":"object",
            "properties":{
                "street_address":{
                    "type":"string"
                },
                "city":{
                    "type":"string"
                },
                "state":{
                    "type":"string"
                }
            },
            "required":[
                "street_address",
                "city",
                "state"
            ]
        }
    },
    "allOf":[
        {
            "$ref":"#/definitions/address"
        },
        {
            "properties":{
                "type":{
                    "enum":[
                        "residential",
                        "business"
                    ]
                }
            }
        }
    ]
}
關(guān)鍵字:anyOf

該關(guān)鍵字的值是一個(gè)非空數(shù)組,數(shù)組里面的每個(gè)元素都必須是一個(gè)有效的JSON Schema。
如果待校驗(yàn)JSON元素能夠通過數(shù)組中的任何一個(gè)JSON Schema校驗(yàn),就算通過校驗(yàn)。
意思是展示任意屬性,建議用requires替代和minProperties替代,示例如下:

 {
    "anyOf":[
        {
            "type":"string"
        },
        {
            "type":"number"
        }
    ]
}
關(guān)鍵字:oneOf

該關(guān)鍵字的值是一個(gè)非空數(shù)組,數(shù)組里面的每個(gè)元素都必須是一個(gè)有效的JSON Schema。
如果待校驗(yàn)JSON元素能且只能通過數(shù)組中的某一個(gè)JSON Schema校驗(yàn),才算真正通過校驗(yàn)。不能通過任何一個(gè)校驗(yàn)和能通過兩個(gè)及以上的校驗(yàn),都不算真正通過校驗(yàn)。
其中之一

{
    "oneOf":[
        {
            "type":"number",
            "multipleOf":5
        },
        {
            "type":"number",
            "multipleOf":3
        }
    ]
}
關(guān)鍵字:not

該關(guān)鍵字的值是一個(gè)JSON Schema。
只有待校驗(yàn)JSON元素不能通過該關(guān)鍵字指定的JSON Schema校驗(yàn)的時(shí)候,待校驗(yàn)元素才算通過校驗(yàn)。
非 * 類型

{
    "not":{
        "type":"string"
    }
}
關(guān)鍵字:default

需要特別注意的是,type關(guān)鍵字的值可以是一個(gè)string,也可以是一個(gè)數(shù)組。
如果type的值是一個(gè)string,則其值只能是以下幾種:null、boolean、object、array、number、string、integer。
如果type的值是一個(gè)數(shù)組,則數(shù)組中的元素都必須是string,且其取值依舊被限定為以上幾種。只要帶校驗(yàn)JSON元素是其中的一種,則通過校驗(yàn)。



我們項(xiàng)目如何集成JSON Schema

  1. 引入JSON Schema的依賴
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>3.1.1</version>
</dependency>
  1. 添加兩個(gè)工具包ReadJsonFile,JsonValidateUtil
    ReadJsonFile:從/src/main/resources目錄中讀取json文件
    JsonValidateUtil:校驗(yàn)json數(shù)據(jù)是否符合schema約定的標(biāo)準(zhǔn)
    文件1:ReadJsonFile
package com.mfw.flight.platform.server.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonNodeReader;

import java.io.*;

/**
 * @Author: sunshaokang
 * @Date: 2018/12/29 上午11:23
 */
public class ReadJsonFile {
    /**
     * 讀取Json文件為String json
     *
     * @param filePath filePath為文件的相對(duì)于resources的路徑
     * @return
     */
    public static String readJsonFileAsString(String filePath) {
        filePath = ReadJsonFile.class.getResource(filePath).getPath();
        String jsonStr = "";
        try {
            File jsonFile = new File(filePath);
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 讀取Json文件為JsonNode
     *
     * @param filePath filePath為文件的絕對(duì)路徑
     * @return
     */
    public static JsonNode readJsonFileAsJsonNode(String filePath) {
        JsonNode instance = null;
        try {
            instance = new JsonNodeReader().fromReader(new FileReader(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return instance;
    }
}

文件2:JsonValidateUtil

package com.mfw.flight.platform.server.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.io.IOException;
import java.util.Iterator;

/**
 * @Author: sunshaokang
 * @Date: 2019/3/27 10:44
 */

@Slf4j
public class JsonValidateUtil {
    private final static JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

    /**
     * 校驗(yàn)JSON
     *
     * @param schema   json模式數(shù)據(jù)(可以理解為校驗(yàn)?zāi)0澹?     * @param instance 需要驗(yàn)證Json數(shù)據(jù)
     * @return
     */
    public static ProcessingReport validatorJsonSchema(String schema, String instance) throws IOException {
        ProcessingReport processingReport = null;

        JsonNode jsonSchema = JsonLoader.fromString(schema);
        JsonNode jsonData = JsonLoader.fromString(instance);
        processingReport = factory.byDefault().getValidator().validateUnchecked(jsonSchema, jsonData);
        boolean success = processingReport.isSuccess();
        if (!success){
            Iterator<ProcessingMessage> iterator = processingReport.iterator();
            while (iterator.hasNext()){
                log.error(String.valueOf(iterator.next()));
            }
        }
        return processingReport;
    }
}
  1. 添加Json文件
    /src/main/resources/json目錄下添加json文件


    image.png
  2. 編寫測(cè)試類驗(yàn)證
    注意:ReadJsonFile.readJsonFileAsString(filePath)
    此方法中filePath為文件相對(duì)于resources目錄的路徑,以/開頭。

@Test
    public void testschema() throws Exception {
        String data = ReadJsonFile.readJsonFileAsString("/json/testString.json");
        String schema = ReadJsonFile.readJsonFileAsString("/json/testSchema.json");
        ProcessingReport processingReport = validatorJsonSchema(schema, data);
        boolean success = processingReport.isSuccess();
        System.out.println(success);
//        如下方法可以用來接口自動(dòng)化
//        Assert.assertTrue(report.isSuccess());
    }
  1. 針對(duì)response校驗(yàn)
    出參校驗(yàn)
response.then().assertThat().body(matchesJsonSchemaInClasspath("/json/flightChangeResponse.json"));

bak

matchesJsonSchemaInClasspath 是從 io.restassured.module.jsv.JsonSchemaValidator 這個(gè)類中靜態(tài)導(dǎo)入的,并且推薦靜態(tài)導(dǎo)入這個(gè)類中的所有方法
該方法中直接寫json文件名即可

其中ProcessingReport對(duì)象中維護(hù)了一迭代器,如果執(zhí)行失敗(執(zhí)行成功時(shí)沒有信息),其提供了一些高級(jí)故障信息。每個(gè)錯(cuò)誤可能包含以下屬性:

  • level: 錯(cuò)誤級(jí)別(應(yīng)該就是error)
  • schema:引起故障的模式的所在位置的 URI
  • instance:錯(cuò)誤對(duì)象
  • domain:驗(yàn)證域
  • keyword:引起錯(cuò)誤的約束key
  • found:現(xiàn)在類型
  • expected:期望類型
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容