背景:
复杂的AJAX应用程序可以与数百个不同的JSON服务进行交互,因此,引入对客户端验证的需求。
在处理校验问题方面有着很多的工具,但是通常可以将它们归为以下几类:
判断数据是否已被正确格式化
手动检查形式有误的数据并尝试纠正
手动检查形式有误的数据并将有误数据丢弃
自动检查形式有误的数据
在这里只讨论自动校验方面的可用工具包中的json schema,son schema项目首页:
JSON schema是一个帮助你定义、校验甚至是修复json数据格式的解决方案。它定义了一整套规则,允许我们通过定义一个schema(本身也是JSON)来描述一个JSON串的数据格式。它有如下优点:
描述你现有的JSON数据的格式;
清晰的、人类/机器可读的文档结构;
* 完全的结构校验,尤其适用于 自动测试 或 验证客户端提交的数据格式。
下面为一个定位信息的json schema例子
//json传输值
{
"data" : {
"id" : 851,
"detail" : "琴千线长征路-万盛南路附近",
"area" : 9480,
"province" : "浙江省",
"parentArea" : 2819,
"lng" : 120.32438,
"district" : "东阳市",
"lat" : 29.136176,
"city" : "金华"
}
}
//定位接口返回值的JSON schema
{
"type" : "object",
"properties" : {
"data" : {
"type" : "object",
"properties" : {
"id" : {
"type" : "integer",
"minimum": 0
},
"detail" : {
"type" : "string"
},
"area" : {
"type" : "integer"
},
"province" : {
"type" : "string",
"pattern" : "^(北京市|天津市|....|浙江省)$"
},
"parentArea" : {
"type" : "integer"
},
"lng" : {
"type" : "number",
"minimum" : 73,
"maximum" : 135
},
"district" : {
"type" : "string"
},
"lat" : {
"type" : "number",
"minimum" : 4,
"maximum" : 54
},
"city" : {
"type" : "string"
}
},
"required" : 【
"id",
"detail",
"area",
"province",
"parentArea",
"lng",
"district",
"lat",
"city"
】
}
},
"required" : 【
"data"
】
}
可以看出:
1、json schema 本身也是一个json串
2、每个schema可以描述一个json实例,并且该json实例里每一个节点都可以用一个schema来描述,因此schema与json一样,本身也是一个层级结构,一个schema中可能嵌套着另外若干层schema
3、json schema 定义的检查规则以数据格式验证为主(字段存在性、字段类型),并可以支持一些简单的数据正确性验证(例如数值范围、字符串的模式等),但不能进行复杂的逻辑校验(例如进价必须小于售价等)。
JS JSON Schema库
表1中简要概述了4个JSON Schema库的特性
表 1. 针对 JavaScript 的 JSON Schema 验证库
库(作者)草案版本支持库的大概规模
JSV: JSON Schema 验证器 (Gary Court)
draft-01、draft-02 和 draft-03
120KB
json-schema (Kris Zyp)
draft-03
10KB(需要 CommonJS)
dojox.json.schema (Kris Zyp)
draft-02
10KB(需要 Dojo)
schema.js (Andreas Kalsch)
draft-02(部分)
10KB(需要 CommonJS)
基于 Dojo 的应用程序可能会使用 dojox.json.schema 库,因为该库包含在工具箱中。支持多个版本的(草案)标准的应用程序可能会使用 JSV。
dojox.json.schema 看上去像是 json-schema 的一个分支,所以它们的用法非常相似。schema.js 只实现 draft-02 的一个子集。所以主要关注的是使用 dojox.json.schema 和 JSV 。
1. dojox.json.schema的使用
[/span>html
[/span>head
[/span>title
[/span>script src=""
type="text/javascript"
[/span>script type="text/javascript"
require(【"dojox/json/schema"】, function() {
// Object to validate
var successObj = {
"foo" : "bar"
};
var failureObj = {
"foo" : 1234
};
// Schema
var schema = {
"type": "object",
"properties" : {
"foo" : {
"type" : "string"
}
}
};
//var result = dojox.json.schema.validate(failureObj, schema);
var result = dojox.json.schema.validate(successObj, schema);
// Check results
if (result.valid) {
alert("Object is valid");
} else {
var errorArr = result.errors;
alert("property : " + errorArr【0】.property + "\nmessage : "
+ errorArr【0】.message);
}
});
[/span>body
Hello, World!
dojox.json.schema这种方法只需要引入一个js包,不过必须是线上的,将dojo那个js下载下来后就报错不能执行。
2. JSV的使用
[/span>head
[/span>title
//代码参考:https://weibo.com/u/7931797389
[/span>script src="js/uri.js" type="text/javascript"
[/span>script src="js/jsv.js" type="text/javascript"
[/span>script src="js/json-schema-draft-03.js" type="text/javascript"
[/span>script type="text/javascript"
// Object to validate
var successObj = {
"foo" : "bar"
};
var failureObj = {
"foo" : 1234
};
// Schema
var schema = {
"type": "object",
"properties" : {
"foo" : {
"type" : "string"
}
}
};
var env = JSV.createEnvironment("json-schema-draft-03");
// validate
var result = env.validate(successObj, schema);
if (result.errors.length === 0) {
alert("Object is valid");
} else {
var errorArr = result.errors;
alert("uri : " + errorArr【0】.uri + "\nmessage : "
+ errorArr【0】.message);
}
[/span>body
Hello, World!
JSV这种方法,需要导入3个js包,这是必须下载后才能使用。
JSV 在 errors 数组中提供了一些高级故障信息。每个错误可能包含以下属性:
message:人类可读的错误消息。
uri:失败对象所在位置的 URI。
schemaUri:引起故障的模式的所在位置的 URI。
Attribute:引起故障的模式约束。
* Details:包含更多详细信息的自由格式数组,比如预期值。
使用对比:
dojox.json.schema只需要引入一个js包,基于 Dojo 的应用程序可能会使用 dojox.json.schema 库,因为该库包含在工具箱中。校验的时候也只需要一行代码即可:var result = dojox.json.schema.validate(successObj, schema); 其中successObj为传入的JSON串,schema为校验规则。
JSV需要引入三个js包,JSV支持draft-01,draft-02,draft-03三种草案,支持多个版本的(草案)标准的应用程序可能会使用 JSV。校验的时候需要根据草案创建环境,然后再进行校验。var env = JSV.createEnvironment(“json-schema-draft-03”);
var result = env.validate(successObj, schema);
其中successObj为传入的JSON串,schema为校验规则。JSV在errors数组中提供了一些高级的故障信息,包括message:可读的错误信息;uri:失败对象所在位置的URI;schemaUri:引起故障的模式所在位置的URI;Attribute:引起故障的模式约束;Details:包含更多详细信息的自由格式数组,如果预期值。
性能对比:
一共执行50次,成功和失败分开执行,每种情况执行25次。然后记录下每次的执行时间,执行10次,取平均值。
dojox.json.schema:0.52, 4.28, 3.54, 4, 3.82, 3.64, 3.76, 4.12, 4.16, 5.6
JSV:4.5, 3.96, 3.88, 3.82, 3.98, 3.96, 3.9, 3.8, 4.1, 4.04
json schema类型每次执行时间(ms)
dojox.json.schema
3.744
JSV
3.994
发现时间相差不多,JSV由于js包在本地,所以每次时间比较稳定;dojox.json.schema由于需要从网络上去加载js包,导致执行时间有时会波动很大。整体来说,就执行过程,dojox.json.schema要快不少。
Java JSON Schema库
表2给出了两种java中使用的JSON Schema库
库名称地址支持草案
fge
draft-04 draft-03
everit
draft-04
建议:
如果在项目中使用了jackson json,那么使用fge是一个好的选择,因为fge就是使用的jackson json。
如果项目中使用的