【问题标题】:Jackson JSON Java nested object and arraysJackson JSON Java 嵌套对象和数组
【发布时间】:2017-02-08 18:43:41
【问题描述】:

我有一个示例嵌套 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 类,其中包含字段 reportId (String) 和 reportDetails(List of ReportDetail ),其中 ReportDetail 是另一个包含字符串字段 code 、 rating 等的类。我需要使用一些 Deserializer、JsonTreeParser 机制吗?谢谢。

【问题讨论】:

  • 你可以只创建各自的父对象,只捕获你正在寻找的东西
  • 我不认为它会那样工作。我需要为每个嵌套对象创建一个 Java 对象。如果有 10 个嵌套对象,我不想在我的类中添加这些对象的详细信息。
  • 您可以通过@JsonProperty 捕获您要查找的内容,如果您只需粘贴 JSON,则可以生成所有 Java 对象的在线实现。您可以摆脱不需要的对象和元素

标签: java json jackson objectmapper


【解决方案1】:

解决方案是jayway Java implementation for JsonPath
JsonPath 是 XML 的 XPath 查询语言的 json 等效项。 查询语言非常强大,从 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"}]}

【讨论】:

  • 您好,感谢您的回复。我在杰克逊 api 中寻找一些东西。我找到了答案。我会把解决方案放在这里。不过还是谢谢。
【解决方案2】:

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

在第一个中,您可以只使用 jsonNode 上的 findValue 方法并传入您要查找的属性/对象的字符串值

    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();
            }
        }
    } 

【讨论】:

  • 非常好。你在我以为我都知道的地方为我提供了新功能:)
  • 很高兴它有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多