使用 Java (Jackson) 在 JSON 中读取嵌套键的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29858248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading value of nested key in JSON with Java (Hymanson)
提问by Jon.H
I'm a new Java programmer coming from a background in Python. I have weather data that's being collected/returned as a JSON with nested keys in it, and I don't understand how pull the values out in this situation. I'm sure this question has been asked before, but I swear I've Googled a great deal and I can't seem to find an answer. Right now I'm using json-simple, but I tried switching to Hymanson and still couldn't figure out how to do this. Since Hymanson/Gson seem to be the most used libraries, I'd would love to see an example using one of those libraries. Below is a sample of the data, followed by the code I've written so far.
我是一名来自 Python 背景的新 Java 程序员。我有天气数据作为 JSON 被收集/返回,其中包含嵌套的键,我不明白在这种情况下如何提取值。我确定这个问题以前有人问过,但我发誓我在谷歌上搜索了很多,但似乎找不到答案。现在我正在使用 json-simple,但我尝试切换到 Hymanson,但仍然不知道如何执行此操作。由于 Hymanson/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"
},
...
}
}
Main 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"));
}
}
The function 'historical' calls another function that returns a JSONObject
'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();
}
}
采纳答案by StaxMan
With Hymanson's tree model (JsonNode
), you have both "literal" accessor methods ('get'), which returns null
for missing value, and "safe" accessors ('path'), which allow you to traverse "missing" nodes. So, for example:
使用 Hymanson 的树模型 ( JsonNode
),您可以同时拥有“文字”访问器方法 ('get')(返回null
缺失值)和“安全”访问器('path'),它允许您遍历“缺失”节点。因此,例如:
JsonNode root = mapper.readTree(inputSource);
int h = root.path("response").path("history").getValueAsInt();
which would return the value at given path, or, if path is missing, 0 (default value)
这将返回给定路径的值,或者,如果缺少路径,则为 0(默认值)
But more conveniently, you can just use JSON pointer expression:
但更方便的是,您可以只使用 JSON 指针表达式:
int h = root.at("/response/history").getValueAsInt();
There are other ways too, and often it is more convenient to actually model your structure as Plain Old Java Object (POJO). Your content could fit something like:
还有其他方法,通常将您的结构实际建模为普通旧 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
}
and if so, you would traverse resulting objects just like any Java objects.
如果是这样,您将像遍历任何 Java 对象一样遍历结果对象。
回答by Neil Davis
Check out Hymanson's ObjectMapper. You can create a class to model your JSON then use ObjectMapper's readValue method to 'deserialize' your JSON String into an instance of your model class. And vice-versa.
查看 Hymanson 的 ObjectMapper。您可以创建一个类来为您的 JSON 建模,然后使用 ObjectMapper 的 readValue 方法将您的 JSON 字符串“反序列化”为您的模型类的实例。反之亦然。
回答by Atmaram
回答by Satyajit Paul
Try jpath API. It's xpath equivalent for JSON Data. You can read data by providing the jpath which will traverse the JSON data and return the requested value.
尝试 jpath API。它相当于 JSON 数据的 xpath。您可以通过提供将遍历 JSON 数据并返回请求值的 jpath 来读取数据。
This Java class is the implementation as well as it has example codes on how to call the APIs.
这个 Java 类是实现,它有关于如何调用 API 的示例代码。
https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java
https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java
Readme -
自述文件 -
https://github.com/satyapaul/jpath/blob/master/README.md
https://github.com/satyapaul/jpath/blob/master/README.md
Example:
例子:
JSON Data:
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"
}
}]
}
Code snippet:
代码片段:
String jPath = "/data[Array][1]/likes[Object]/summary[Object]/total_count[String]";
String value = JSONDataReader.getStringValue(jPath, jsonData);