使用 Java 在 JSON 中读取嵌套密钥的值(Jackson)

2022-09-01 01:47:31

我是一名来自Python背景的新Java程序员。我有天气数据被收集/返回为JSON,其中包含嵌套键,我不明白在这种情况下如何提取值。我敢肯定这个问题以前问过,但我发誓我已经在谷歌上搜索了很多,我似乎找不到答案。现在我正在使用json-simple,但我尝试切换到Jackson,但仍然不知道如何做到这一点。由于 Jackson/Gson 似乎是最常用的库,我很想看到一个使用其中一个库的示例。下面是数据示例,后跟我到目前为止编写的代码。

{
    "response": {
        "features": {
            "history": 1
        }
     },
    "history": {
        "date": {
            "pretty": "April 13, 2010",
            "year": "2010",
            "mon": "04",
            "mday": "13",
            "hour": "12",
            "min": "00",
            "tzname": "America/Los_Angeles"
        },
        ...
    }
}

主要功能

public class Tester {

    public static void main(String args[]) throws MalformedURLException, IOException, ParseException {
        WundergroundAPI wu =  new WundergroundAPI("*******60fedd095");

        JSONObject json = wu.historical("San_Francisco", "CA", "20100413");

        System.out.println(json.toString());
        System.out.println();
        //This only returns 1 level. Further .get() calls throw an exception
        System.out.println(json.get("history"));
    }
}

函数“historical”调用另一个返回 JSONObject 的函数

public static JSONObject readJsonFromUrl(URL url) throws MalformedURLException, IOException, ParseException {

    InputStream inputStream = url.openStream();

    try {
        JSONParser parser = new JSONParser();
        BufferedReader buffReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));

        String jsonText = readAll(buffReader);
        JSONObject json = (JSONObject) parser.parse(jsonText);
        return json;
    } finally {
        inputStream.close();
    }
}

答案 1

使用 Jackson 的树模型 (),您既有“字面”访问器方法 ('get'),前者返回缺失值,后者也具有“安全”访问器('path'),前者允许您遍历“缺失”节点。例如:JsonNodenull

JsonNode root = mapper.readTree(inputSource);
int h = root.path("response").path("history").getValueAsInt();

这将返回给定路径处的值,或者,如果缺少路径,则返回 0(默认值)

但更方便的是,您可以只使用 JSON 指针表达式:

int h = root.at("/response/history").getValueAsInt();

还有其他方法,通常将结构建模为普通旧Java对象(POJO)更方便。您的内容可以符合以下条件:

public class Wrapper {
  public Response response;
} 
public class Response {
  public Map<String,Integer> features; // or maybe Map<String,Object>
  public List<HistoryItem> history;
}
public class HistoryItem {
  public MyDate date; // or just Map<String,String>
  // ... and so forth
}

如果是这样,您将像遍历任何Java对象一样遍历生成的对象。


答案 2

使用 Jsonpath

Integer h = JsonPath.parse(json).read(“$.response.repository.history”, Integer.class);