jsonの形式がJavaの要件を満たしているかどうかを確認する方法

WBOY
リリース: 2023-05-15 16:01:16
転載
4066 人が閲覧しました

JSON スキーマ

JSON スキーマは、JSON データ構造を検証するための強力なツールです。スキーマはパターンまたはルールとして理解できます。

Json スキーマは、Json メタデータを定義するために使用される一連の語彙とルールを定義し、メタデータも Json データの形式で表現されます。 Json メタデータは、Json データが満たす必要がある仕様を定義します。仕様には、メンバー、構造、型、制約などが含まれます。

JSON スキーマは、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 に必要です。スキーマの書き込み

検証したいデータ形式が次の場合:

{
    "data": [
        {
            "sex": "男",
            "name": "王小明",
            "age": 18
        },
        {
            "sex": "女",
            "name": "王小红",
            "age": 17
        }
    ],
    "type": "human"
}
ログイン後にコピー

外側は型とデータ、内側は配列で、配列の属性には性別、名前、年齢が含まれます

スキーマ ファイルの書き込み

{
    "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 のデータ形式を記述します。外側の層にはフィールドの型とデータが必要で、名前の最大長は制限されています maxLength は 3、性別は列挙値で、男性または女性のみです。2 つの文字列、年齢は数値型です。

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. まとめ

リストに角括弧

[] を使用してスキーマが記述されている場合、検証中に配列の最初のスキーマのみがチェックされます。これは次のような落とし穴です。

{
    "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の形式がJavaの要件を満たしているかどうかを確認する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート