java校驗json的格式是否符合要求的操作方法
在日常開發(fā)過程中,會有這樣的需求,校驗?zāi)硞€json是否是我們想要的數(shù)據(jù)格式,如果每個層級去判斷,基本不太可能實現(xiàn),當然java有開源的工具,我們可以直接使用
JSON Schema
JSON Schema 是用于驗證 JSON 數(shù)據(jù)結(jié)構(gòu)的強大工具,Schema可以理解為模式或者規(guī)則。
Json Schema定義了一套詞匯和規(guī)則,這套詞匯和規(guī)則用來定義Json元數(shù)據(jù),且元數(shù)據(jù)也是通過Json數(shù)據(jù)形式表達的。Json元數(shù)據(jù)定義了Json數(shù)據(jù)需要滿足的規(guī)范,規(guī)范包括成員、結(jié)構(gòu)、類型、約束等。
JSON Schema 就是json的格式描述、定義、模板,有了他就可以生成任何符合要求的json數(shù)據(jù)
json-schema-validator
在java中,對json數(shù)據(jù)格式的校驗,使用 json-schema-validator
,具體實例如下:
1. 引入依賴
<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
是必須要引入的,他們?yōu)?json-schema-validator
必須的
2. 編寫schema
如果我們要校驗的數(shù)據(jù)格式如下:
{ "data": [ { "sex": "男", "name": "王小明", "age": 18 }, { "sex": "女", "name": "王小紅", "age": 17 } ], "type": "human" }
外面是type和data,里面是一個數(shù)組,數(shù)組屬性包括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的數(shù)據(jù)格式,外層必須字段type、data,里面限制了name的最大長度 maxLength
為3,sex 為枚舉值,只可取 男、女兩個字符串,age 為number類型。
3. 代碼實現(xiàn)
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 + " 字段長度過長"); // 如果不在枚舉范圍內(nèi) } 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 + "不在枚舉范圍內(nèi)"); } 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 + " 類型錯誤,現(xiàn)有類型: " + found + ", 預期類型:" + expected); } }); } } catch (IOException | ProcessingException e) { log.error("校驗json格式異常", e); } return map; }
以上代碼首先獲取了 要校驗的json的標準文件 validator.json
,然后調(diào)用 JsonSchemaFactory.byDefault().getValidator().validate(jsonNodeSchema, jsonNode, true)
方法對傳進來的json 進行了校驗,這里 true
的意思是深度檢查,如果沒有這個參數(shù),校驗json的時候遇到第一個錯誤,就直接返回了
接下來構(gòu)建測試方法
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); }
4. 執(zhí)行結(jié)果
{sex=sex字段值錯誤,未知不在枚舉范圍內(nèi), name=王小明1 字段長度過長, age=age 類型錯誤,現(xiàn)有類型: string, 預期類型:["integer","number"]}
5. 整理總結(jié)
如果schema 編寫的時候,對列表使用了中括號 []
,那么當校驗的時候只會校驗數(shù)組中的第一個,這是一個坑,如下
{ "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 數(shù)組的第一條數(shù)據(jù),其他的有錯誤也不會報錯!!
JSON Schema 功能很強大,支持表達式,支持是否允許額外屬性,支持邏輯組合等,如果想了解更新json校驗的知識,請參考下面參考文檔
參考文檔
到此這篇關(guān)于java校驗json的格式是否符合要求的文章就介紹到這了,更多相關(guān)java校驗json格式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Java匯總Spock框架Mock靜態(tài)資源經(jīng)驗
這篇文章主要介紹了基于Java匯總Spock框架Mock靜態(tài)資源經(jīng)驗,前面講了?Spock框架Mock對象、方法經(jīng)驗總結(jié),今天分享一下Spock框架中Mock靜態(tài)資源的實踐經(jīng)驗匯總。分成靜態(tài)資源和混合場景,需要的朋友可以參考一下2022-02-02Java模擬rank/over函數(shù)實現(xiàn)獲取分組排名的方法詳解
這篇文章主要為大家詳細介紹了Java模擬rank()、over()函數(shù)獲取分組排名的方法設(shè)計及實現(xiàn),文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-04-04webuploader在springMVC+jquery+Java開發(fā)環(huán)境下的大文件分片上傳的實例代碼
這篇文章主要介紹了webuploader在springMVC+jquery+Java開發(fā)環(huán)境下的大文件分片上傳的實例代碼,需要的朋友可以參考下2017-04-04詳細介紹idea如何設(shè)置類頭注釋和方法注釋(圖文)
本篇文章主要介紹了idea如何設(shè)置類頭注釋和方法注釋(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12