何為JsonSchema
了解元數(shù)據(jù)的同學(xué)很容易理解JsonSchema和Json的關(guān)系斋荞。元數(shù)據(jù)是描述數(shù)據(jù)的數(shù)據(jù),包括數(shù)據(jù)的屬性胎撤、位置信息、獲取方式等断凶,而通常JsonSchema伤提,主要描述Json數(shù)據(jù)的屬性信息。
下面是一個(gè)簡單的描述Person基本信息的Json數(shù)據(jù)
{
"firstName": "John",
"lastName": "Doe",
"age": 21
}
其對應(yīng)的元數(shù)據(jù)為:
{
"title": "Person", // Json描述的實(shí)體名稱
"type": "object", // Json實(shí)體類型
"properties": { // Json實(shí)體包括的屬性信息
"firstName": { // 屬性名
"type": "string", // 屬性對應(yīng)的Json類型
"description": "The person's first name." // 屬性描述
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0 // 最小值
}
}
}
JsonShema的完整語法非常靈活懒浮,具體可以參照http://json-schema.org/understanding-json-schema/
有什么用
Json數(shù)據(jù)的應(yīng)用范圍非常廣:接口數(shù)據(jù)參數(shù)及返回?cái)?shù)據(jù)飘弧,傳輸數(shù)據(jù),大數(shù)據(jù)存儲(chǔ)數(shù)據(jù)等砚著,在這些應(yīng)用中JsonShema可以輔助:
- 描述Json數(shù)據(jù)次伶,方便理解數(shù)據(jù)內(nèi)容,Json數(shù)據(jù)的釋義文檔完全可以選擇JsonShema
- 方便機(jī)器理解Json以實(shí)現(xiàn)測試自動(dòng)化稽穆,例如對于數(shù)據(jù)進(jìn)行校驗(yàn)冠王,接口測試等
接口測試實(shí)例
JsonSchema進(jìn)行接口測試Java實(shí)現(xiàn)
引入Jar包
<dependency>
<groupId>org.everit.json</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.5.1</version>
<scope>provided</scope>
</dependency>
編寫JsonUtil類進(jìn)行校驗(yàn)
@Slf4j
public class JsonUtil {
public static boolean validateJsonWithSchema(String schema, JSONObject jsonObject) {
if (ObjectUtils.isEmpty(schema) || jsonObject == null) {
Assert.fail("validateJsonWithSchema error, schema | jsonObject invalid");
return false;
}
Schema jsonSchema;
try {
JSONObject json = new JSONObject(new JSONTokener(schema));
jsonSchema = SchemaLoader.load(json);
} catch (JSONException e) {
log.error("validateJsonWithSchema fail", e);
Assert.fail("validateJsonWithSchema fail, invalid jsonschema");
return false;
}
try {
jsonSchema.validate(jsonObject);
} catch (ValidationException e) {
log.error("validateJsonWithSchema fail: {}", e.getMessage());
Assert.fail("validateJsonWithSchema fail");
return false;
}
return true;
}
}
為了詳細(xì)的展示所有校驗(yàn)失敗的地方,我們對ValidationException進(jìn)行解析:
private static String getReason(ValidationException exception) {
if (ObjectUtils.isEmpty(exception)) {
return "";
}
String reason = "";
List<ValidationException> exceptions = new ArrayList();
exceptions.add(exception);
int len = exceptions.size();
int i = 0;
while (i < len) {
ValidationException e = exceptions.get(i);
if (ObjectUtils.isEmpty(e.getCausingExceptions())) {
reason += "\n" + e.getMessage();
i += 1;
} else {
exceptions.addAll(e.getCausingExceptions());
i += 1;
len = exceptions.size();
}
}
return reason;
}
定義接口結(jié)果Schema
可以通過https://easy-json-schema.github.io/自動(dòng)生成初版的JsonSchema
{
"type": "object",
"required": ["result", "msg", "data"],
"properties": {
"result": {
"type": "number",
"minimum": 1,
"maximun": 1
},
"msg": {
"type": "string"
},
"data": {
"type": "object",
"required": ["dataCount", "list"],
"properties": {
"dataCount": {
"type": "number",
"minimum": 1
},
"list": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["userId", "reqId", "reqTime", "photoList"],
"properties": {
"userId": {
"type": "string",
"minLength": 10
},
"reqId": {
"type": "string",
"minLength": 20
},
"reqTime": {
"type": "string",
"minLength": 13
},
"photoList": {
"type": "array",
"minItems": 6,
"items": {
"type": "object",
"required": ["itemId"],
"properties": {
"itemId": {
"type": "string",
"minLength": 10
},
"title": {
"type": "string"
}
}
}
}
}
}
}
}
}
運(yùn)行結(jié)果