JSON Schema 是用於驗證 JSON 資料結構的強大工具,Schema可以理解為模式或規則。
Json Schema定義了一套詞彙和規則,這套詞彙和規則用來定義Json元數據,而元數據也是透過Json數據形式表達的。 Json元資料定義了Json資料需要滿足的規範,規範包括成員、結構、類型、約束等。
JSON Schema 是json的格式描述、定義、模板,有了他就可以產生任何符合要求的json資料
#在java中,對json資料格式的校驗,使用json-schema-validator
,具體實例如下:
<dependency> <groupId>com.github.fge</groupId> <artifactId>json-schema-validator</artifactId> <version>2.2.6</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.0</version> </dependency>
#jackson -core
和jackson-core
是必須要引入的,他們為json-schema-validator
必須的
#如果我們要校驗的資料格式如下:
{ "data": [ { "sex": "男", "name": "王小明", "age": 18 }, { "sex": "女", "name": "王小红", "age": 17 } ], "type": "human" }
外面是type和data,裡面是一個數組,數組屬性包括sex、name、age
寫schema檔
{ "type": "object", "properties": { "type": { "type": "string" }, "data": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "maxLength": 3 }, "sex": { "enum": [ "男", "女" ] }, "age": { "type": "number" } }, "required": [ "name", "sex", "age" ] } } }, "required": [ "type", "data" ] }
以上json描述了目標json的資料格式,外層必須欄位type、data,裡面限制了name的最大長度maxLength
為3,sex 為枚舉值,只可取男、女兩個字串,age 為number型別。
public Map validatorJsonUnchecked(String body) { Map<String, String> map = new HashMap<>(); String filePath = "validator" + File.separator + "validator.json"; ObjectMapper objectMapper = new ObjectMapper(); try { JsonNode jsonNodeSchema = objectMapper.readTree(ResourceUtil.readUtf8Str(filePath)); JsonNode jsonNode = objectMapper.readTree(body); ProcessingReport processingReport = JsonSchemaFactory.byDefault().getValidator().validate(jsonNodeSchema, jsonNode, true); if (!processingReport.isSuccess()) { processingReport.forEach(processingMessage -> { JsonNode missing = processingMessage.asJson().get("missing"); String keyword = processingMessage.asJson().get("keyword").asText(); // 如果缺失字段 if (!Objects.isNull(missing)) { missing.forEach(miss -> { String text = miss.asText(); map.put(text, text + " 字段缺失"); }); // 如果字段超长 } else if ("maxLength".equals(keyword)) { String field = processingMessage.asJson().get("instance").get("pointer").asText(); String value = processingMessage.asJson().get("value").asText(); field = field.substring(field.lastIndexOf("/") + 1); map.put(field, value + " 字段长度过长"); // 如果不在枚举范围内 } else if ("enum".equals(keyword)) { String field = processingMessage.asJson().get("instance").get("pointer").asText(); String value = processingMessage.asJson().get("value").asText(); field = field.substring(field.lastIndexOf("/") + 1); map.put(field, field + "字段值错误," + value + "不在枚举范围内"); } else if ("type".equals(keyword)) { String field = processingMessage.asJson().get("instance").get("pointer").asText(); String found = processingMessage.asJson().get("found").asText(); String expected = processingMessage.asJson().get("expected").toString(); field = field.substring(field.lastIndexOf("/") + 1); map.put(field, field + " 类型错误,现有类型: " + found + ", 预期类型:" + expected); } }); } } catch (IOException | ProcessingException e) { log.error("校验json格式异常", e); } return map; }
以上程式碼首先取得了要校驗的json的標準檔validator.json
,然後呼叫JsonSchemaFactory.byDefault() .getValidator().validate(jsonNodeSchema, jsonNode, true)
方法對傳進來的json 進行了校驗,這裡true
的意思是深度檢查,如果沒有這個參數,校驗json的時候遇到第一個錯誤,就直接回傳了
接下來建置測試方法
public static void main(String[] args) { ValidatorService validatorService = new ValidatorServiceImpl(); Map<String, Object> body = new HashMap<>(); HashMap<String, Object> one = new HashMap<String, Object>() {{ put("name", "王小明"); put("sex", "男"); put("age", 18); }}; HashMap<String, Object> two = new HashMap<String, Object>() {{ put("name", "王小明1"); put("sex", "未知"); put("age", "18"); }}; body.put("type", "human"); body.put("data", Arrays.asList(one,two)); Map map = validatorService.validatorJsonUnchecked(JSONUtil.toJsonStr(body)); System.out.println(map); }
{sex=sex欄位值錯誤,未知不在枚舉範圍內, name=王小明1 字段長度過長, age=age 類型錯誤,現有型別: string, 預期型別:["integer","number"]}
如果schema 寫的時候,對清單使用了中括號[]
,那麼當校驗的時候只會校驗數組中的第一個,這是一個坑,如下
{ "type": "object", "properties": { "type": { "type": "string" }, "data": { "type": "array", "items": [ { "type": "object", "properties": { "name": { "type": "string", "maxLength": 3 }, "sex": { "enum": [ "男", "女" ] }, "age": { "type": "number" } }, "required": [ "name", "sex", "age" ] } ] } }, "required": [ "type", "data" ] }
如果是這樣的話,只會校驗data 數組的第一條數據,其他的有錯誤也不會報錯! !
以上是java怎麼校驗json的格式是否符合要求的詳細內容。更多資訊請關注PHP中文網其他相關文章!