使用Java在没有给定pojo的情况下使用给定的键解析复杂的json和xml

时间:2019-05-22 06:31:22

标签: java json xml api

我的要求是解析大量后端响应,可以是json或xml。我现在不知道他们的回应结构。因此,我必须以这样一种方式编写一个Java工具,即我的工具应该能够基于配置文件解析响应,服务团队将在运行我的工具之前对其进行配置,以便他们能够知道这些值,它们将不得不通过我的工具进行检索。例如,如果后端json或xml响应如下所示,并且我的配置显示为Employee.details.referenced [0] .type,则通过工具检索的值应为“客户支持”。我将无法使用pojo或与后端响应耦合的东西,因为我不知道后端响应,并且我的同一个工具应该适用于不同的后端,这些后端以不同的结构输出响应:

Json:

{
    "Employee": [
        {
            "id": "12345678",
            "service": "ps",
            "origin": {
                "address": {
                    "addressLocality": "India"
                }
            },
            "destination": {
                "address": {
                    "addressLocality": "US"
                }
            },
            "status": {
                "timestamp": "2019-01-29T21:02:49Z",
                "location": {
                    "address": {
                        "addressLocality": "Germany"
                    }
                },
                "Code": "xyz",
                "description": "Services"
            },
            "details": {
                "references": [
                    {
                        "number": "0003030891",
                        "type": "customer-support"
                    }
                ]
            }
        }
    ]
}

XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <Employee>
      <element>
         <destination>
            <address>
               <addressLocality>US</addressLocality>
            </address>
         </destination>
         <details>
            <references>
               <element>
                  <number>0003030891</number>
                  <type>customer-support</type>
               </element>
            </references>
         </details>
         <id>12345678</id>
         <origin>
            <address>
               <addressLocality>India</addressLocality>
            </address>
         </origin>
         <service>ps</service>
         <status>
            <Code>xyz</Code>
            <description>Services</description>
            <location>
               <address>
                  <addressLocality>Germany</addressLocality>
               </address>
            </location>
            <timestamp>2019-01-29T21:02:49Z</timestamp>
         </status>
      </element>
   </Employee>
</root>

我试图检查java和xml saxparser中的json解析器。但是,所有人似乎都必须提前知道后端响应。

2 个答案:

答案 0 :(得分:1)

Jackson可以将JSON和XML都解析为Map<String, Object>。值的类型为Object,因为除了String属性之外,它还可以是List或代表JSON / XML子树的Map

答案 1 :(得分:1)

另一位发布者已经指出了Jackson库,但我想补充一下我的想法:

Jackson能够将String(或几个I / O源中的任何其他源)直接解析为JsonNode

String json = backEndProvider.fetch(); // example call
JsonNode node = new ObjectMapper().readTree(json);

然后,您可以使用其.get()方法访问生成的JsonNode的子级:

JsonNode child = node.get("childKey");

此外,可以使用多种转换方法来访问终值。例如,如果您知道child是文本,则可以通过以下方式获得child的值:

String childValue = child.asText();

另请参阅this Baeldung article

从这里,您可以将用户的输入String(例如Employee.details.referenced[0].type)解析为键数组(例如["Employee", "details", "referenced[0]", "type"]),然后递归访问根元素,直到获取足够的值为止,并在每个位置检查如果键是数组访问操作,则返回阶段。如果您没有任何类型信息,则需要从参考解析器返回JsonNodeObject

对于诸如referenced[0]之类的数组访问,请注意ArrayNode的继承物ObjectNodeits get() method is overriden to use an int

请注意,上述解决方案与杰克逊的XmlMapper相同。