背景

大量接口都按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:可以定义枚举类型,限定某些字段必须在这个范围内的校验