使用Java(Jackson)读取JSON中嵌套键的值

我是一名来自Python背景的新Java程序员。 我有收集/返回的天气数据作为带有嵌套键的JSON,我不明白在这种情况下如何拉出值。 我确定之前已经问过这个问题,但是我发誓我已经用Google搜索了很多内容,我似乎无法找到答案。 现在我正在使用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" }, ... } } 

主function

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

使用Jackson的树模型( JsonNode ),你有两个“文字”访问器方法(’get’),它为缺失值返回null ,以及“安全”访问器(’path’),它允许你遍历“丢失”节点。 所以,例如:

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

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

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

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

还有其他方法,通常将结构实际建模为Plain Old Java Object(POJO)更方便。 您的内容可能类似于:

 public class Wrapper { public Response response; } public class Response { public Map features; // or maybe Map public List history; } public class HistoryItem { public MyDate date; // or just Map // ... and so forth } 

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

查看Jackson的ObjectMapper。 您可以创建一个类来为JSON建模,然后使用ObjectMapper的readValue方法将您的JSON String“反序列化”为模型类的实例。 反之亦然。

使用Jsonpath

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

试试jpath API。 它是JSON Data的xpath等价物。 您可以通过提供将遍历JSON数据并返回所请求值的jpath来读取数据。

这个Java类是实现,它有关于如何调用API的示例代码。

https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

自述 –

https://github.com/satyapaul/jpath/blob/master/README.md

例:

JSON数据:

 { "data": [{ "id": "13652355666_10154605514815667", "uid": "442637379090660", "userName": "fanffair", "userFullName": "fanffair", "userAction": "recommends", "pageid": "usatoday", "fanPageName": "USA TODAY", "description": "A missing Indonesian man was found inside a massive python on the island of Sulawesi, according to local authorities and news reports. ", "catid": "NewsAndMedia", "type": "link", "name": "Indonesian man swallowed whole by python", "picture": "https:\/\/external.xx.fbcdn.net\/safe_image.php?d=AQBQf3loH5-XP6hH&w=130&h=130&url=https%3A%2F%2Fwww.gannett-cdn.com%2F-mm-%2F1bb682d12cfc4d1c1423ac6202f4a4e2205298e7%2Fc%3D0-5-1821-1034%26r%3Dx633%26c%3D1200x630%2Flocal%2F-%2Fmedia%2F2017%2F03%2F29%2FUSATODAY%2FUSATODAY%2F636263764866290525-Screen-Shot-2017-03-29-at-9.27.47-AM.jpg&cfs=1&_nc_hash=AQDssV84Gt83dH2A", "full_picture": "https:\/\/external.xx.fbcdn.net\/safe_image.php?d=AQBQf3loH5-XP6hH&w=130&h=130&url=https%3A%2F%2Fwww.gannett-cdn.com%2F-mm-%2F1bb682d12cfc4d1c1423ac6202f4a4e2205298e7%2Fc%3D0-5-1821-1034%26r%3Dx633%26c%3D1200x630%2Flocal%2F-%2Fmedia%2F2017%2F03%2F29%2FUSATODAY%2FUSATODAY%2F636263764866290525-Screen-Shot-2017-03-29-at-9.27.47-AM.jpg&cfs=1&_nc_hash=AQDssV84Gt83dH2A", "message": "Akbar Salubiro was reported missing after he failed to return from harvesting palm oil.", "link": "http:\/\/www.usatoday.com\/story\/news\/nation-now\/2017\/03\/29\/missing-indonesian-man-swallowed-whole-reticulated-python\/99771300\/", "source": "", "likes": { "summary": { "total_count": "500" } }, "comments": { "summary": { "total_count": "61" } }, "shares": { "count": "4" } }] } 

代码段:

 String jPath = "/data[Array][1]/likes[Object]/summary[Object]/total_count[String]"; String value = JSONDataReader.getStringValue(jPath, jsonData);