web-dev-qa-db-fra.com

Lecture de la valeur de la clé imbriquée dans JSON avec Java (Jackson)

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();
    }
}
20
Jon.H

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.

51
StaxMan

Utilisez Jsonpath

Entier h = JsonPath.parse (json) .read ("$. Response.repository.history", Integer.class);

4
Atmaram

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.

1
Neil Davis

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);
0
Satyajit Paul