JSON スキーマは、JSON データ構造を検証するための強力なツールです。スキーマはパターンまたはルールとして理解できます。
Json スキーマは、Json メタデータを定義するために使用される一連の語彙とルールを定義し、メタデータも Json データの形式で表現されます。 Json メタデータは、Json データが満たす必要がある仕様を定義します。仕様には、メンバー、構造、型、制約などが含まれます。
JSON スキーマは、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": "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 つの文字列、年齢は数値型です。
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); }
#5. まとめリストに角括弧{sex=sex フィールド値エラー、不明は含まれていません列挙範囲、name=王小明1 フィールドの長さが長すぎます、age=age タイプエラー、既存のタイプ: string、予期されるタイプ: ["integer","number"]}
[] を使用してスキーマが記述されている場合、検証中に配列の最初のスキーマのみがチェックされます。これは次のような落とし穴です。
{ "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 サイトの他の関連記事を参照してください。