Je suis un nouveau programmeur Java issu d'un environnement Python. J'ai des données météorologiques qui sont collectées/renvoyées sous forme de JSON avec des clés imbriquées, et je ne comprends pas comment extraire les valeurs dans cette situation. Je suis sûr que cette question a déjà été posée, mais je jure que j'ai beaucoup cherché sur Google et que je n'arrive pas à trouver de réponse. En ce moment, j'utilise json-simple, mais j'ai essayé de passer à Jackson et je ne comprenais toujours pas comment faire cela. Jackson/Gson semblant être les bibliothèques les plus utilisées, j'aimerais beaucoup voir un exemple utilisant l'une de ces bibliothèques. Vous trouverez ci-dessous un échantillon des données, suivi du code que j'ai écrit jusqu'à présent.
{
"response": {
"features": {
"history": 1
}
},
"history": {
"date": {
"pretty": "April 13, 2010",
"year": "2010",
"mon": "04",
"mday": "13",
"hour": "12",
"min": "00",
"tzname": "America/Los_Angeles"
},
...
}
}
Fonction principale
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"));
}
}
La fonction 'historique' appelle une autre fonction qui retourne un 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();
}
}
Avec le modèle d'arborescence de Jackson (JsonNode
), vous avez à la fois des méthodes d'accès littérales ('get'), qui renvoie null
pour la valeur manquante et des accesseurs «sûrs» ('path'), qui vous permettent de parcourir les nœuds "manquants". Donc, par exemple:
JsonNode root = mapper.readTree(inputSource);
int h = root.path("response").path("history").getValueAsInt();
qui renverrait la valeur au chemin donné, ou, si le chemin est manquant, 0 (valeur par défaut)
Mais plus facilement, vous pouvez simplement utiliser l'expression de pointeur JSON:
int h = root.at("/response/history").getValueAsInt();
Il existe également d’autres méthodes, et il est souvent plus pratique de modéliser votre structure en tant qu’objet simple et ancien (POJO) . Votre contenu pourrait contenir quelque chose comme:
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
}
et si tel est le cas, vous traverserez les objets résultants comme n'importe quel objet Java.
Utilisez Jsonpath
Entier h = JsonPath.parse (json) .read ("$. Response.repository.history", Integer.class);
Découvrez ObjectMapper de Jackson. Vous pouvez créer une classe pour modéliser votre JSON, puis utiliser la méthode readValue de ObjectMapper pour "désérialiser" votre chaîne JSON en une instance de votre classe de modèle. Et vice versa.
Essayez jpath API. C'est l'équivalent de xpath pour les données JSON. Vous pouvez lire les données en fournissant le chemin jpath qui traversera les données JSON et renverra la valeur demandée.
Cette classe Java est l'implémentation et des exemples de codes expliquant comment appeler les API.
https://github.com/satyapaul/jpath/blob/master/JSONDataReader.Java
Lisez-moi -
https://github.com/satyapaul/jpath/blob/master/README.md
Exemple:
Données 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"
}
}]
}
Extrait de code:
String jPath = "/data[Array][1]/likes[Object]/summary[Object]/total_count[String]";
String value = JSONDataReader.getStringValue(jPath, jsonData);