背景
大量接口都按JSON传输,按照协议标准定义,JSON的合法性校验可以在代码里写死但是看着有点脏,今天我想安利一下JSON Schema。Json Schema也是一个json文件,可以用于对JSON内容、格式等校验。下面开干~~~
代码参考
Maven依赖
<!--<!– https://mvnrepository.com/artifact/com.github.everit-org.json-schema/org.everit.json.schema –>-->
<dependency>
<groupId>com.github.everit-org.json-schema</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.9.2</version>
</dependency>
接口协议描述
数据项 | 数据项编码 | 描述 | 必填项 | 校验 |
矿井名称 | mineName | 矿井名称参见煤矿编码” | 必填 | |
矿井编号 | mineCode | 矿井编号参见煤矿编码” | 必填 | |
定位卡号 | pCardNO | 描述该人员配置定位卡号,参见5.1编码规则 | 必填 | |
人员姓名 | name | 必填 | ||
性别 | sex | |||
出生日期 | birthDate | |||
工种 | workType | 参见“5.2.2人员工种职务类型” | 必填 | |
职务 | post | 对区队长以上(含区队长)描述其实际职务,区队长以下人员,描述其实际工种即可 | 必填 | |
身份证号 | socialNO | |||
集团工号 | ceNO | 正式员工使用集团的8位工号;外委人员使用分配的临时工号(d开头的8位工号) | 必填 | |
用工类别 | insider | 描述人员的类型,即正式员工或是外委人员。 外委人员:0 正式员工:1 | 必填 | |
所属区队/部门 | depart | 描述人员所属的实际区队名称或部门名称 | 必填 | |
区队部门类型 | departType | 描述人员所属的实际区队名称或部门的分类,参见“5.2.17区队部门类型” | 必填 | |
工作时限 | limitTime | 描述该人员的设定的工作时限,单位:h(小时) | 必填 | |
主要工作地点 | workPlace | |||
学历 | education | |||
血型 | bloodType | |||
婚姻状况 | marStatus | |||
联系电话 | callNO | |||
手机号码 | mobileNO | |||
家庭住址 | address | |||
配卡时间 | activationDate | 描述为人员配卡的时间 | 必填 | 格式要求见7.3 |
人员信息状态 | personInforStatus | 描述人员的当前的用工状态 | 必填 | |
创建时间 | createDate | 描述该人员的信息创建时间 | 必填 | 格式要求见7.3 |
待校验的JSON示例
{
"total": 2, // 2为定位分站数量,即data中jSON对象的数量
"data": [{
"mineName": "煤矿1",
"mineCode": "10000000",
"pCardNO": "CCC0025FE",
"name": "李友才",
"sex": "男",
"birthDate": "1975-02-07",
"workType": "1003",
"post": "总工程师",
"socialNO": "11111111111111111111",
"ceNO": "11687432",
"insider": "1",
"depart": "矿领导",
"departType": "9003",
"limitTime": "8",
"workPlace": "全矿",
"education": "本科",
"bloodType": "A",
"marStatus": "已婚",
"callNO": "",
"mobileNO": "",
"address": "××省范德市201",
"activationDate": "2021-02-07 01:00:23",
"personInforStatus": "301",
"createDate": "2021-02-07 01:00:23"
},{
"mineName": "煤矿1",
"mineCode": "19997799",
"pCardNO": "CCC00123E",
"name": "张三",
"sex": "男",
"birthDate": "1975-02-07",
"workType": "1007",
"post": "支架工",
"socialNO": "11111111111111111111",
"ceNO": "11687452",
"insider": "1",
"depart": "综采二队",
"departType": "9005",
"limitTime": "8",
"workPlace": "×××综采工作面",
"education": "本科",
"bloodType": "A",
"marStatus": "已婚",
"callNO": "",
"mobileNO": "",
"address": "××省范德市203",
"activationDate": "2021-02-07 01:00:23",
"personInforStatus": "301",
"createDate": "2021-02-07 01:00:23"
}]
}
代码
/**
fileName是JsonSchema的名称
fileInfoJson是待校验的JSON内容
*/
public String validatJsonSchema(String fileName, String fileInfoJson) {
String result = "";
try {
InputStream inputStream = null;
inputStream = this.class.getClassLoader().getResourceAsStream(fileName + "_schema.json");
if (null == inputStream) {
return result;
}
String str = IOUtils.toString(inputStream, Charset.forName("utf-8"));
JSONObject jsonSchema = new JSONObject(new JSONTokener(str));
JSONObject data = new JSONObject(fileInfoJson.trim());
Schema schema = SchemaLoader.load(jsonSchema);
schema.validate(data);
} catch (ValidationException e) {
List<String> list = e.getAllMessages();
for (String message : list) {
result = result + "," + message;
}
} catch (Exception e) {
result = e.getMessage();
e.printStackTrace();
}
return result;
}
JsonSchema示例
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"properties": {
"total": {
"type": "number"
},
"data": {
"type": "array",
"items": {
"$id": "#/subItems",
"type": "object",
"properties": {
"mineName": {
"$id": "#/subItems/properties/mineName",
"type": "string",
"title": "The mineName Schema"
},
"mineCode": {
"$id": "#/subItems/properties/mineCode",
"type": "string",
"title": "The mineCode Schema",
"default": "",
"examples": [
"10109091-1"
],
"enum": [
"11111199",
"12222222",
"14444448",
"15555556",
"16666663",
"17777773"
]
},
"pCardNO": {
"$id": "#/subItems/properties/pCardNO",
"type": "string",
"title": "The pCardNO Schema",
"examples": [
"CEH000068"
],
"pattern": "^(CCC|BBB)[\\w]{6}$"
},
"name": {
"$id": "#/subItems/properties/name",
"type": "string",
"title": "The name Schema",
"default": ""
},
"workType": {
"$id": "#/subItems/properties/workType",
"type": "string",
"title": "The workType Schema",
"examples": [
"1001"
],
"enum": ["1001","1002","1003","1004","1005","1006","1007","1008","1009","1010","1021"]
},
"post": {
"$id": "#/subItems/properties/post",
"type": "string",
"title": "The post Schema",
"default": ""
},
"ceNO": {
"$id": "#/subItems/properties/ceNO",
"type": "string",
"title": "The ceNO Schema",
"examples": [
"e0001994"
],
"pattern": "^(e|[1-9])\\d{7}$"
},
"insider": {
"$id": "#/subItems/properties/insider",
"type": "string",
"title": "The insider Schema",
"examples": [
"0"
],
"enum": ["0","1"]
},
"depart": {
"$id": "#/subItems/properties/depart",
"type": "string",
"title": "The depart Schema",
"default": ""
},
"departType": {
"$id": "#/subItems/properties/departType",
"type": "string",
"title": "The departType Schema",
"default": "",
"examples": [
"9001"
],
"enum": ["9001","9002","9003","9004","9005","9006","9007","9008","9009"]
},
"limitTime": {
"$id": "#/subItems/properties/limitTime",
"type": "string",
"title": "The limitTime Schema",
"pattern": "^([1-9][0-9]*)$"
},
"activationDate": {
"$id": "#/subItems/properties/activationDate",
"type": "string",
"title": "The activationDate Schema",
"default": "",
"examples": [
"2018-09-11 15:58:40"
],
"pattern": "^(\\d{4})-([0-1]\\d)-([0-3]\\d)\\s([0-2]?\\d):([0-5]\\d):([0-5]\\d)$"
},
"personInforStatus": {
"$id": "#/subItems/properties/personInforStatus",
"type": "string",
"title": "The personInforStatus Schema",
"default": "",
"examples": [
"301"
],
"enum": ["301","302","303","304"]
},
"createDate": {
"$id": "#/subItems/properties/createDate",
"type": "string",
"title": "The createDate Schema",
"default": "",
"examples": [
"2018-09-11 15:58:40"
],
"pattern": "^(\\d{4})-([0-1]\\d)-([0-3]\\d)\\s([0-5]\\d):([0-5]\\d):([0-5]\\d)$"
}
},
"required": [
"mineName",
"mineCode",
"pCardNO",
"name",
"workType",
"post",
"ceNO",
"insider",
"depart",
"departType",
"limitTime",
"activationDate",
"personInforStatus",
"createDate"
]
}
}
},
"required": [
"total",
"data"
]
}
JSONShema校验响应信息示例
#/data/0/enterAreaDate: string [] does not match pattern ^(\\d{4})-([0-1]\\d)-([0-3]\\d)\\s([0-5]\\d):([0-5]\\d):([0-5]\\d)$,#/data/0/cardEnergyLimit: string [] does not match pattern ^(100|[1-9]?\\d(\\.\\d\\d?\\d?)?)%$|0$,#/data/0/alarmStatus: 310 is not a valid enum value,#/data/1/enterAreaDate: string [] does not match pattern ^(\\d{4})-([0-1]\\d)-([0-3]\\d)\\s([0-5]\\d):([0-5]\\d):([0-5]\\d)$,#/data/1/cardEnergyLimit: string [] does not match pattern ^(100|[1-9]?\\d(\\.\\d\\d?\\d?)?)%$|0$,#/data/1/alarmStatus: 310 is not a valid enum value
Json-schema 说明
1.$schema: json-schema版本信息的描述
2.$id:定义了schema的URI,可以定义子节点的指向
3.title and description: 描述shema用途的
4.type: 用于定义JSON对象的实体类型,取值范围有Object,Array,String,Number,boolean,null
5.properties: 用于定义具体属性值,并可以在里面指定属性的限值范围,正则匹配,字段类型,长度限值等信息
6.required: 用于指定哪些字段是必须的。
7.items: 顾名思议,就是列表或数组中的集合,与type为array配合使用,items里面可以定义type,properties,required等 属性信息
8.enum:可以定义枚举类型,限定某些字段必须在这个范围内的校验