【问题标题】:JSON Path: how to convert URN references to local referencesJSON 路径:如何将 URN 引用转换为本地引用
【发布时间】:2018-10-10 16:46:09
【问题描述】:

在使用 Maven org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.0-alpha2 将 JSON 模式文件转换为 Java 类时,我遇到了与无法解决的 urn 引用相关的错误。

这是一个示例错误消息:

[ERROR] Failed to execute goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.0-alpha2:generate (default) on project model-reservation: Execution default of goal org.jsonschema2pojo:jsonschema
2pojo-maven-plugin:1.0.0-alpha2:generate failed: Unrecognised URI, can't resolve this: urn:jsonschema:com:lumina:pnr:model:Reference: unknown protocol: urn -> [Help 1]

这里是它引用的带有 $ref 元素的 JSON,它导致了异常:

    "remarkFields": {
      "type": "object",
      "additionalProperties": {
        "type": "array",
        "items": {
          "type": "object",
          "id": "urn:jsonschema:com:lumina:pnr:model:FileFinishingField",
          "properties": {
            "lineNumber": {
              "type": "integer"
            },
            "name": {
              "type": "string"
            },
            "value": {
              "type": "string"
            },
            "references": {
              "type": "array",
              "items": {
                "type": "object",
                "$ref": "urn:jsonschema:com:lumina:pnr:model:Reference"
              }
            }
          }
        }
      }
    }

如何将这些转换为 Java 中的本地引用,并使用转换输出成功地将我的代码转换为使用 org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.0.0-alpha2 Maven 插件的 Java 类?

【问题讨论】:

    标签: java maven jsonschema


    【解决方案1】:

    可能有更好的方法来解决这个问题,但一种可能的解决方案是:

    使用递归方法将urn样式引用转换为本地引用:

    这是使用 Jackson 库的递归方法:

    private static final String ITEMS = "items";
    private static final String ID = "id";
    private static final String PROPERTIES = "properties";
    private static final String ADDITIONAL_PROPERTIES = "additionalProperties";
    private static final String REF = "$ref";
    
    private static void parseReferences(JsonNode jsonNode, String path) {
        if (jsonNode.has(ID)) {
            typeMap.put(jsonNode.get(ID).asText(), path);
            final JsonNode properties = jsonNode.get(PROPERTIES);
            final Iterator<Map.Entry<String, JsonNode>> fields = properties.fields();
            path += "/" + PROPERTIES;
    
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                parseReferences(entry.getValue(), path + "/" + entry.getKey());
            }
        } else if (jsonNode.has(ITEMS)) {
            final JsonNode item = jsonNode.get(ITEMS);
            parseReferences(item, path + "/" + ITEMS);
        } else if (jsonNode.has(REF)) {
            ObjectNode objectNode = (ObjectNode) jsonNode;
            objectNode.set(REF, new TextNode(typeMap.get(jsonNode.get(REF).asText())));
        } else if (jsonNode.has(ADDITIONAL_PROPERTIES)) {
            JsonNode additionalProperties = jsonNode.get(ADDITIONAL_PROPERTIES);
            parseReferences(additionalProperties, path + "/" + ADDITIONAL_PROPERTIES);
        }
    }
    

    这是我在实例化 JAXB 解析器后调用此方法的方式:

    private static void writeSchemaToFile(ObjectMapper jaxbObjectMapper, String origPath, String path) throws Exception {
        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(origPath);
        try (Reader r = new InputStreamReader(resourceAsStream, "UTF-8")) {
            JsonNode root = jaxbObjectMapper.readTree(r);
            parseReferences(root, "#");
            String changedJson = jaxbObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
            final Path targetPath = Paths.get(path);
            if (!Files.exists(targetPath)) {
                Path parent = targetPath.getParent();
                if (parent != null) {
                    Files.createDirectories(parent);
                }
            }
            try (Writer writer = Files.newBufferedWriter(targetPath, Charset.forName("UTF-8"), StandardOpenOption.CREATE)) {
                writer.write(changedJson);
            }
        }
    }
    

    如果你调用这个方法,它会将问题中指定的JSON转换为:

    "remarkFields" : {
      "type" : "object",
      "additionalProperties" : {
        "type" : "array",
        "items" : {
          "type" : "object",
          "id" : "urn:jsonschema:com:lumina:pnr:model:FileFinishingField",
          "properties" : {
            "lineNumber" : {
              "type" : "integer"
            },
            "name" : {
              "type" : "string"
            },
            "value" : {
              "type" : "string"
            },
            "references" : {
              "type" : "array",
              "items" : {
                "type" : "object",
                "$ref" : "#/properties/passengers/items/properties/reference"
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 您的代码示例缺少变量typeMap,但除此之外它似乎工作正常。添加顶层:static HashMap&lt;String, String&gt; typeMap = new HashMap&lt;&gt;();
    猜你喜欢
    • 2022-10-12
    • 2014-04-27
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    相关资源
    最近更新 更多