RESTFUL 接口裏,經常需要檢查 json 參數,幾次老記不住,就查了下,寫下以後備用。
以下是python jsonschema 的一個例子,包含了絕大多數常用檢測,註釋看完就明白了。
from jsonschema import validate, draft7_format_checker
from jsonschema.exceptions import SchemaError, ValidationError
schema = {
# 該關鍵字用於指定JSON Schema版本: draft-07
"$schema": "http://json-schema.org/draft-07/schema#",
# 描述對應的JSON元素,title相對來說,更加簡潔
"title": "book info",
# 描述對應的JSON元素,description更加傾向於詳細描述相關信息
"description": "some information about book",
# 該關鍵字用於限定待校驗JSON元素所屬的數據類型,取值可爲:object,array,integer,number,string,boolean,null
"type": "object",
# 用於指定JSON對象中的各種不同key應該滿足的校驗邏輯,
# 如果待校驗JSON對象中所有值都能夠通過該關鍵字值中定義的對應key的校驗邏輯,每個key對應的值,都是一個JSON Schema,則待校驗JSON對象通過校驗。
"properties": {
"id": {
"description": "The unique identifier for a book",
"type": "integer",
"minimum": 1
},
"name": {
"description": "book name",
"type": "string",
"minLength": 3,
"maxLength": 30
},
"info": {
"description": "simple information about book",
"type": "string",
"minLength": 10,
"maxLength": 60
},
"tips": {
"anyOf": [ # 滿足其中一個類型 就行
{"type": "string", "minLength": 10, "maxLength": 60},
{"type": "number", "minimum": 5.0}
]
},
"price": {
"description": "book price",
"type": "number",
# 能被0.5整除
"multipleOf": 0.5,
# 這裏取等,5.0=<price<=99999.0
"minimum": 5.0,
"maximum": 99999.0,
# 若使用下面這兩個關鍵字則 5.0<price<99999.0
# "exclusiveMinimum": 5.0,
# "exclusiveMaximum": 99999.0
},
"tags": {
"type": "array",
"items": [
{
"type": "string",
"minLength": 2,
"maxLength": 8
},
{
"type": "number",
"minimum": 1.0
}
],
# 待校驗JSON數組第一個元素是string類型,且可接受的最短長度爲5個字符,第二個元素是number類型,且可接受的最小值爲10
# 剩餘的其他元素是string類型,且可接受的最短長度爲2。
"additonalItems": {
"type": "string",
"miniLength": 2
},
# 至少一個
"miniItems": 1,
# 最多5個
"maxItems": 5,
# 值爲true時,所有元素都具有唯一性時,才能通過校驗。
"uniqueItems": True
},
"date": {
"description": "書籍出版日期",
"type": "string",
# 可以是以下取值:date、date-time(時間格式)、email(郵件格式)、hostname(網站地址格式)、ipv4、ipv6、uri等。
# 使用format關鍵字時,在實例化validator時必須給它傳format_checker參數,值如:draft7_format_checker, 網址:
# https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft7Validator
"format": "date",
},
"bookcoding": {
"description": "書籍編碼",
"type": "string",
# 符合該關鍵字指定的正則表達式,纔算通過校驗。
"pattern": "^[A-Z]+[a-zA-Z0-9]{12}$"
},
"other": {
"description": "其他信息",
"type": "object",
"properties": {
"info1": {
"type": "string"
},
"info2": {
"type": "string"
}
}
}
},
# 指定了待校驗JSON對象可以接受的最少 一級key 的個數
"minProperties": 3,
# 指定了待校驗JSON對象可以接受的最多 一級key 的個數。
"maxProperties": 7,
# patternProperties對象的每一個一級key都是一個正則表達式,value都是一個JSON Schema。
# 只有待校驗JSON對象中的一級key,通過與之匹配的patternProperties中的一級正則表達式,對應的JSON Schema的校驗,纔算通過校驗。
# 下面的JSON Schema表示, 所有以a開頭的一級key的value都必須是number,
"patternProperties": {
"^a": {
"type": "number"
},
},
# 如果待校驗JSON對象中存在,既沒有在properties中被定義,又沒有在patternProperties中被定義,那麼這些一級key必須通過additionalProperties的校驗。
"additionalProperties": {
"desc": {
"type": "string",
"minLength": 1
},
},
# 該關鍵字限制了JSON對象中必須包含哪些一級key。
# 如果一個JSON對象中含有required關鍵字所指定的所有一級key,則該JSON對象能夠通過校驗。
"required": ["id", "name", "info", "price"]
}
json_data = {
"id": 1,
"name": "jarvis手冊",
"info": "賈維斯平臺使用手冊1",
"price": 5.5,
"tags": ["jar"],
"date": "2019-5-25",
"other": {
"info1": "1111",
"info2": "222"
}
}
try:
validate(instance=json_data, schema=schema, format_checker=draft7_format_checker)
except SchemaError as e:
print("驗證模式schema出錯:\n出錯位置:{}\n提示信息:{}".format(" --> ".join([i for i in e.path]), e.message))
except ValidationError as e:
print("json數據不符合schema規定:\n出錯字段:{}\n提示信息:{}".format(" --> ".join([i for i in e.path]), e.message))
else:
print("驗證成功!")