首页 > 解决方案 > JSON 架构:外部 JSON 架构文件未验证 json

问题描述

我正在尝试使用 json 模式验证 json,问题是我为复杂对象创建了不同的 json 模式文件。我需要使用 ref 标签包含在主模式中。并尝试使用everit lib验证我的json。模式已加载,但是当我尝试验证我的示例 json 时,它没有验证内部模式对象。

内部对象.json

   {
    "$id": "http://example.com/example.json",
    "type": "object",
    "definitions": {},
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
        "typeCode": {
            "$id": "/properties/typeCode",
            "type": "string"
        },
        "description": {
            "$id": "/properties/description",
            "type": "string"
        },
        "expDate": {
            "$id": "/properties/expDate",
            "type": "string"
        },
        "issuingCountry": {
            "$id": "/properties/issuingCountry",
            "type": "string"
        }
    },
    "required": [
        "typeCode",
        "description",
        "expDate",
        "issuingCountry"
    ]   
}

外部对象.JSON

    {
    "$id": "http://example.com/example.json",
    "type": "object",
    "definitions": {
    },
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
        "firstName": {
            "$id": "/properties/firstName",
            "type": "string"
        },
        "lastName": {
            "$id": "/properties/lastName",
            "type": "string"
        },
        "innerObject": {
            "$id": "#item",
            "type": "object",
            "$ref": "file://com/mypack/innerObject.json"
        }
    },
    "required": [
        "firstName",
        "lastName",
        "innerObject"
    ]
}

这两个文件都在我的项目 src/main/resource

我有用于测试我的模式的 json 验证器类。

import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;

public class JSONSchemaValidator {
    public static void main(String[] args) {
        JSONObject jsonSchema = new JSONObject(new JSONTokener(JSONSchemaValidator.class
                .getResourceAsStream("/com/schema/outer.schema.json")));
        JSONObject outerJson = new JSONObject();

        JSONObject innerJson = new JSONObject();

        innerJson.put("expDate", "expDate");
        innerJson.put("typeCode", "typeCode");

        outerJson.put("firstName", "firstName");
        outerJson.put("lastName", "lastName");

        outerJson.put("innerObject", innerJson);

        Schema schema = SchemaLoader.load(jsonSchema);

        System.out.println(schema.getDescription());
        schema.validate(outerJson);

        System.out.println("done");

    }
}

它使用模式验证第一级,但不用于内部级别。任何人都可以建议做错了什么,因此它没有验证 json。

我要验证的示例 JSON 是:

{"firstName":"firstName","lastName":"lastName","innerObject":{"expDate":"expDate","typeCode":"typeCode"}}

它应该抛出一个错误,如“typeCode”、“description”、“expDate”、issuingCountry” 4 个字段是强制性的,在输入中我只传递了两个。所以对于剩下的两个它应该抛出一个错误。

标签: javajsonjsonschema

解决方案


只需在带有 ref 标签的外部 json 中提供内部 json 文件。

例如 :

{
    "$id": "http://example.com/example.json",
    "type": "object",
    "definitions": {
    },
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
        "firstName": {
            "$id": "/properties/firstName",
            "type": "string"
        },
        "lastName": {
            "$id": "/properties/lastName",
            "type": "string"
        },
        "innerObject": {                
            "$ref": "innerObject.json"
        }
    },
    "required": [
        "firstName",
        "lastName",
        "innerObject"
    ]
}

在 Java 代码中,您需要设置 resolutionScope,您需要提供内部 json 的路径。

String path="file:" + Paths.get("").toUri().getPath() + "PATH_OF_YOUR_JSONSchema";
        System.out.println("older"+ path); 
        if (path.contains(" ")) {
             path=path.replaceAll(" ", "%20");           
         }
SchemaLoader sl=SchemaLoader.builder().schemaJson(jsonSchema).resolutionScope(path ).build();
Schema schema=sl.load().build();
schema.validate(yourJsonObject);

推荐阅读