首頁 >Java >java教程 >java怎麼校驗json的格式是否符合要求

java怎麼校驗json的格式是否符合要求

WBOY
WBOY轉載
2023-05-15 16:01:164127瀏覽

JSON Schema

JSON Schema 是用於驗證 JSON 資料結構的強大工具,Schema可以理解為模式或規則。

Json Schema定義了一套詞彙和規則,這套詞彙和規則用來定義Json元數據,而元數據也是透過Json數據形式表達的。 Json元資料定義了Json資料需要滿足的規範,規範包括成員、結構、類型、約束等。

JSON Schema 是json的格式描述、定義、模板,有了他就可以產生任何符合要求的json資料

json-schema-validator

#在java中,對json資料格式的校驗,使用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 -corejackson-core 是必須要引入的,他們為json-schema-validator 必須的

2. 寫schema

#如果我們要校驗的資料格式如下:

{
    "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型別。

3. 程式碼實作

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);
    }

4.執行結果

{sex=sex欄位值錯誤,未知不在枚舉範圍內, name=王小明1 字段長度過長, age=age 類型錯誤,現有型別: string, 預期型別:["integer","number"]}

#5. 整理總結

如果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中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除