Jackson JSON Java 嵌套对象和数组

Jackson JSON Java nested object and arrays

我有一个嵌套 json 对象的示例,如下所示:

{
"payload": {
"id": "1",
"apiResp": {
  "apiRespDetails": {
    "report": {
      "reportId": "reportid1",
      "reportDetails": [
        {
          "code": "1",
          "rating": "good"
        },
        {
          "code": "2",
          "rating": "bad"
        },
        {
          "code": "3",
          "rating": "fair"
        }
      ]
     }
   }
  }
 }
}

我只需要报表对象,不需要其父对象的任何详细信息。使用 Jackson API 获得它的最佳方法是什么?

我创建了一个名为 Report.java 的 Java Class 字段 reportId (String) 和 reportDetails(List of ReportDetail ),其中 ReportDetail 是另一个 class 字段代码,评级等。我需要使用一些反序列化器,JsonTreeParser 机制吗?谢谢。

解决方案是jayway Java implementation for JsonPath
JsonPath is the json equivalent for the XPath XML 的查询语言。 查询语言非常强大,如 github 自述文件中的示例所示。

这是一个快速入门的演示:

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import com.jayway.jsonpath.*;
import net.minidev.json.JSONArray;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.*;

public class JsonPathDemo2
{
    public static void main(String[] args)
    {
        // query: search for any report property below root 
        String jsonPathQuery = "$..report";

        try (InputStream is = Files.newInputStream(Paths.get("C://temp/xx.json"))) {
            Object parsedContent = 
                    Configuration.defaultConfiguration().jsonProvider().parse(is, StandardCharsets.UTF_8.name());
            System.out.println("hasJsonPath? " + hasJsonPath(jsonPathQuery).matches(parsedContent));
            Object obj = JsonPath.read(parsedContent, jsonPathQuery);
            System.out.println("parsed object is of type " + obj.getClass());
            System.out.println("parsed object to-string " + obj);
            JSONArray arr = (JSONArray)obj;
            System.out.println("first array item is of type " + arr.get(0).getClass());
            System.out.println("first array item to-string " + arr.get(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:

hasJsonPath? true
parsed object is of type class net.minidev.json.JSONArray
parsed object to-string [{"reportId":"reportid1","reportDetails":[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]}]
first array item is of type class java.util.LinkedHashMap
first array item to-string {reportId=reportid1, reportDetails=[{"code":"1","rating":"good"},{"code":"2","rating":"bad"},{"code":"3","rating":"fair"}]}

您好,使用 jackson fasterxml api 找到了两个解决方案。

在第一个中,您可以在 json 节点上使用 findValue 方法并传入您要查找的 property/object 的字符串值

    String jsonresponse = "above json string";
    JsonFactory jsonFactory = new JsonFactory();
    JsonParser jp = jsonFactory.createParser(jsonresponse);
    jp.setCodec(new ObjectMapper());
    JsonNode jsonNode = jp.readValueAsTree();
    JsonNode reportNode = jsonNode.findValue("report");     
    ObjectMapper mapper = new ObjectMapper();
    Report report = mapper.convertValue(reportNode, Report.class);

此其他解决方案使用 JsonToken,它遍历 json 响应,直到找到您要查找的内容为止

    JsonFactory factory = new JsonFactory();       
    factory.setCodec(new ObjectMapper());
    JsonParser  parser  = factory.createParser(jsonresponse);
    while(!parser.isClosed()){
        JsonToken jsonToken = parser.nextToken();

        if(JsonToken.FIELD_NAME.equals(jsonToken)){
            String fieldName = parser.getCurrentName();
            if("report".equals(fieldName)) {
                jsonToken = parser.nextToken();
                Report report = parser.readValueAs(Report.class);       
            } else {
                jsonToken = parser.nextToken();
            }
        }
    }