Comment analyser JSON en Java


1049

J'ai le texte JSON suivant. Comment puis - je analyser pour obtenir les valeurs de pageName, pagePic, post_id, etc.?

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

7
Les bibliothèques JSON intégrées à Java sont le moyen le plus rapide de le faire, mais d'après mon expérience, GSON est la meilleure bibliothèque pour analyser un JSON en POJO sans douleur.
Iman Akbari

16
C'est la première question hautement votée et protégée dont j'ai trouvé les réponses les plus déroutantes
Riyafa Abdul Hameed

6
@JaysonMinard a accepté. Intervention demandée pour le mod. Cela devrait être vraiment fermé. J'ai d'abord supposé (à tort) que je ne pouvais pas le faire tant que la question était protégée, alors je l'ai non protégée et j'ai fait mon truc. Re-protégé maintenant pour empêcher les réponses de faible répétition et autres, en attendant un mod.
Mena

4
"Cette question ne montre aucun effort de recherche" - Infobulle du bouton Downvote
Jean-François Corbett

6
Cette question est en cours de discussion sur Meta .
Mark Amery

Réponses:


755

La bibliothèque org.json est facile à utiliser. Exemple de code ci-dessous:

import org.json.*;

String jsonString = ... ; //assign your JSON String here
JSONObject obj = new JSONObject(jsonString);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......
}

Vous pouvez trouver plus d'exemples de: Parse JSON en Java

Pot téléchargeable: http://mvnrepository.com/artifact/org.json/json


15
Je suis d'accord avec @StaxMan. J'ai juste essayé org.json et c'est horriblement lourd. Cela ne fonctionne vraiment pas avec les types de collection Java standard, par exemple.
Ken Williams

7
@StaxMan Je choisirais org.jsonplutôt que d'autres bibliothèques pour une analyse JSON simple sans même regarder. Il s'agit de la bibliothèque de référence créée par Douglas Crockford (le découvreur JSON).
Omar Al-Ithawi,

31
@OmarIthawi c'est tout simplement idiot. C'est une preuve de concept avec une API maladroite, une implémentation inefficace. Je pense qu'il vaut mieux considérer les bibliothèques sur leurs propres mérites, au lieu d'essayer de déduire la qualité de la visibilité de ses auteurs - Doug a accompli beaucoup de choses, mais cela ne change pas vraiment les qualités de la bibliothèque particulière. Il y a 10 ans, c'était le seul match en ville, mais depuis lors, il y a eu beaucoup de progrès positifs. C'est comme Struts of json libs.
StaxMan

12
org.json est parmi les pires bibliothèques json. Il faut regarder l'ensemble des fonctionnalités et les performances des bibliothèques json disponibles avant de choisir. Voici une référence que j'ai faite en comparant jackson, gson, org.json, genson en utilisant JMH: github.com/fabienrenaud/java-json-benchmark . jackson est clairement le gagnant ici.
fabien

4
La licence n'inclut aucune licence Open Source couramment utilisée, et elle détient également des droits d'auteur.
Christian Vielma

538

Pour les besoins de l'exemple, supposons que vous ayez une classe Personavec juste un name.

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Google GSON ( Maven )

Mon préféré en ce qui concerne la grande sérialisation / désérialisation JSON des objets.

Gson g = new Gson();

Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John

System.out.println(g.toJson(person)); // {"name":"John"}

Mise à jour

Si vous souhaitez retirer un seul attribut, vous pouvez également le faire facilement avec la bibliothèque Google:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John

Org.JSON ( Maven )

Si vous n'avez pas besoin de désérialisation d'objet mais simplement pour obtenir un attribut, vous pouvez essayer org.json ( ou regarder l'exemple GSON ci-dessus! )

JSONObject obj = new JSONObject("{\"name\": \"John\"}");

System.out.println(obj.getString("name")); //John

Jackson ( Maven )

ObjectMapper mapper = new ObjectMapper();
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);

System.out.println(user.name); //John

16
Bonne réponse. Une suggestion pour une amélioration mineure: GSON et Jackson prennent également en charge l'utilisation de la représentation arborescente JSON (pour Jackson, ce sont des JsonNodes, GSON a quelque chose de similaire). Cela peut être utile d'afficher des extraits, car cela est similaire à la seule façon offerte par org.json.
StaxMan

Deux autres bibliothèques qui méritent d'être mentionnées (dans un souci d'exhaustivité): json-simple et JSONP d'Oracle
jake stayman

3
@NeonWarge, pourquoi? Il me semble que cette réponse suppose que l'on a déjà défini une classe Java qui contient exactement les mêmes champs que la chaîne JSON, rien de moins et rien de plus. C'est une hypothèse assez forte.
Andrea Lazzarotto

1
json-simple et jsonp d'oracle fonctionnent très bien: github.com/fabienrenaud/java-json-benchmark Pour les performances, choisissez jackson ou dsljson.
fabien

GSON ne prend pas en charge le filtrage dynamique des champs à des niveaux autres que root!
Gangnus

102
  1. Si l'on veut créer un objet Java à partir de JSON et vice versa, utilisez des pots tiers GSON ou JACKSON, etc.

    //from object to JSON 
    Gson gson = new Gson();
    gson.toJson(yourObject);
    
    // from JSON to object 
    yourObject o = gson.fromJson(JSONString,yourObject.class);
  2. Mais si l'on veut juste analyser une chaîne JSON et obtenir des valeurs, (OU créer une chaîne JSON à partir de zéro pour l'envoyer sur le fil), il suffit d'utiliser le pot JaveEE qui contient JsonReader, JsonArray, JsonObject etc. Vous voudrez peut-être télécharger l'implémentation de cette spec comme javax.json. Avec ces deux pots, je suis capable d'analyser le json et d'utiliser les valeurs.

    Ces API suivent en fait le modèle d'analyse DOM / SAX de XML.

    Response response = request.get(); // REST call 
        JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
        JsonArray jsonArray = jsonReader.readArray();
        ListIterator l = jsonArray.listIterator();
        while ( l.hasNext() ) {
              JsonObject j = (JsonObject)l.next();
              JsonObject ciAttr = j.getJsonObject("ciAttributes");

4
@nondescript Si je devais deviner, je dirais qu'il a été sous-voté car il ne répond pas à la question de l'affiche originale: "Quel est le code requis?" Les réponses qui ont été votées ont fourni des extraits de code.
jewbix.cube

4
Remarque: Jackson et GSON prennent tous les deux en charge les liaisons de type arborescence et / ou Maps / Lists, il n'est donc pas nécessaire d'utiliser le package Java EE (javax.json). javax.json a peu à offrir au-delà de Jackson ou de GSON.
StaxMan

Je suggère d'ajouter un lien vers la bibliothèque JavaEE.
Basil Bourque

72

l'analyseur quick-json est très simple, flexible, très rapide et personnalisable. Essayez-le

Fonctionnalités:

  • Conforme à la spécification JSON (RFC4627)
  • Analyseur JSON hautes performances
  • Prend en charge l'approche d'analyse flexible / configurable
  • Validation configurable des paires clé / valeur de toute hiérarchie JSON
  • Facile à utiliser # Très faible encombrement
  • Déclenche des exceptions conviviales et faciles à suivre pour les développeurs
  • Prise en charge de la validation personnalisée enfichable - Les clés / valeurs peuvent être validées en configurant des validateurs personnalisés au fur et à mesure qu'ils sont rencontrés
  • Prise en charge de l'analyseur de validation et de non-validation
  • Prise en charge de deux types de configuration (JSON / XML) pour l'utilisation de l'analyseur de validation JSON rapide
  • Nécessite JDK 1.5
  • Aucune dépendance aux bibliothèques externes
  • Prise en charge de la génération JSON via la sérialisation d'objets
  • Prise en charge de la sélection du type de collection pendant le processus d'analyse

Il peut être utilisé comme ceci:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);

3
Existe-t-il un javadoc?
jboi

24
Ce package ne peut pas gérer les valeurs vides lors de l'analyse. Par exemple: ... "description": "" ... lève une exception
Ivan

6
J'ai résolu ce problème (et bien d'autres) dans code.google.com/p/quick-json/issues/detail?id=11 J'espère que l'auteur donnera le temps de le corriger dans la version officielle.
noamik

8
Parmi les fonctionnalités répertoriées, rien n'est unique par rapport aux autres options - et la revendication de hautes performances n'est prise en charge par rien; contrairement aux bibliothèques plus matures (Gson, Jackson, Genson, Boon) qui sont incluses dans des benchmarks comme github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest ou developer.com/lang/jscript/… - I n'ont pas vu cette bibliothèque incluse dans les tests, ou mentionne qu'elle est largement utilisée.
StaxMan

26
Ce projet semble être mort et ne semble plus être hébergé dans le référentiel Maven central.
8bitjunkie

40

Vous pouvez utiliser Google Gson .

À l'aide de cette bibliothèque, il vous suffit de créer un modèle avec la même structure JSON. Ensuite, le modèle est automatiquement rempli. Vous devez appeler vos variables en tant que clés JSON ou utiliser @SerializedNamesi vous souhaitez utiliser des noms différents.

JSON

De votre exemple:

{
    "pageInfo": {
        "pageName": "abc",
        "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
        {
            "post_id": "123456789012_123456789012",
            "actor_id": "1234567890",
            "picOfPersonWhoPosted": "http://example.com/photo.jpg",
            "nameOfPersonWhoPosted": "Jane Doe",
            "message": "Sounds cool. Can't wait to see it!",
            "likesCount": "2",
            "comments": [],
            "timeOfPost": "1234567890"
        }
    ]
}

Modèle

class MyModel {

    private PageInfo pageInfo;
    private ArrayList<Post> posts = new ArrayList<>();
}

class PageInfo {

    private String pageName;
    private String pagePic;
}

class Post {

    private String post_id;

    @SerializedName("actor_id") // <- example SerializedName
    private String actorId;

    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private String likesCount;
    private ArrayList<String> comments;
    private String timeOfPost;
}

Analyse

Vous pouvez maintenant analyser à l'aide de la bibliothèque Gson:

MyModel model = gson.fromJson(jsonString, MyModel.class);

Importation Gradle

N'oubliez pas d'importer la bibliothèque dans le fichier Gradle de l'application

implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions

Génération automatique de modèles

Vous pouvez générer automatiquement un modèle à partir de JSON en utilisant des outils en ligne comme celui-ci .


38

Presque toutes les réponses données nécessitent une désérialisation complète du JSON en un objet Java avant d'accéder à la valeur de la propriété d'intérêt. Une autre alternative, qui ne suit pas cette route, est d'utiliser JsonPATH qui est comme XPath pour JSON et permet de traverser des objets JSON.

Il s'agit d'une spécification et les bonnes personnes de JayWay ont créé une implémentation Java pour la spécification que vous pouvez trouver ici: https://github.com/jayway/JsonPath

Donc, fondamentalement, pour l'utiliser, ajoutez-le à votre projet, par exemple:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>${version}</version>
</dependency>

et utiliser:

String pageName = JsonPath.read(yourJsonString, "$.pageInfo.pageName");
String pagePic = JsonPath.read(yourJsonString, "$.pageInfo.pagePic");
String post_id = JsonPath.read(yourJsonString, "$.pagePosts[0].post_id");

etc...

Consultez la page de spécification JsonPath pour plus d'informations sur les autres façons de transverser JSON.


Il s'agit d'une très bonne bibliothèque, en particulier pour la lecture et la mise à jour de JSON, mais méfiez-vous des problèmes connus concernant cette bibliothèque. Voir [1]: github.com/json-path/JsonPath/issues/272 [2]: github.com/json-path/JsonPath/issues/375
papigee

38

A - Explication

Vous pouvez utiliser les bibliothèques Jackson pour lier la chaîne JSON aux instances POJO ( Plain Old Java Object ). POJO est simplement une classe avec uniquement des champs privés et des méthodes getter / setter publiques. Jackson va parcourir les méthodes (à l'aide de la réflexion ) et mappe l'objet JSON dans l'instance POJO lorsque les noms de champ de la classe correspondent aux noms de champ de l'objet JSON.

Dans votre objet JSON, qui est en fait un objet composite , l'objet principal se compose de deux sous-objets. Ainsi, nos classes POJO devraient avoir la même hiérarchie. J'appellerai tout l'objet JSON en tant qu'objet Page . L' objet Page se compose d'un objet PageInfo et d'un tableau d'objets Post .

Nous devons donc créer trois classes POJO différentes;

  • Page Class, un composite de PageInfo Class et un tableau de post- instances
  • PageInfo, classe
  • Classe de messages

Le seul paquet que j'ai utilisé est Jackson ObjectMapper, ce que nous faisons est de lier des données;

com.fasterxml.jackson.databind.ObjectMapper

Les dépendances requises, les fichiers jar sont listés ci-dessous;

  • jackson-core-2.5.1.jar
  • jackson-databind-2.5.1.jar
  • jackson-annotations-2.5.0.jar

Voici le code requis;

B - Classe POJO principale: page

package com.levo.jsonex.model;

public class Page {

    private PageInfo pageInfo;
    private Post[] posts;

    public PageInfo getPageInfo() {
        return pageInfo;
    }

    public void setPageInfo(PageInfo pageInfo) {
        this.pageInfo = pageInfo;
    }

    public Post[] getPosts() {
        return posts;
    }

    public void setPosts(Post[] posts) {
        this.posts = posts;
    }

}

C - Classe POJO enfant: PageInfo

package com.levo.jsonex.model;

public class PageInfo {

    private String pageName;
    private String pagePic;

    public String getPageName() {
        return pageName;
    }

    public void setPageName(String pageName) {
        this.pageName = pageName;
    }

    public String getPagePic() {
        return pagePic;
    }

    public void setPagePic(String pagePic) {
        this.pagePic = pagePic;
    }

}

D - Classe POJO enfant: poste

package com.levo.jsonex.model;

public class Post {

    private String post_id;
    private String actor_id;
    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private int likesCount;
    private String[] comments;
    private int timeOfPost;

    public String getPost_id() {
        return post_id;
    }

    public void setPost_id(String post_id) {
        this.post_id = post_id;
    }

    public String getActor_id() {
        return actor_id;
    }

    public void setActor_id(String actor_id) {
        this.actor_id = actor_id;
    }

    public String getPicOfPersonWhoPosted() {
        return picOfPersonWhoPosted;
    }

    public void setPicOfPersonWhoPosted(String picOfPersonWhoPosted) {
        this.picOfPersonWhoPosted = picOfPersonWhoPosted;
    }

    public String getNameOfPersonWhoPosted() {
        return nameOfPersonWhoPosted;
    }

    public void setNameOfPersonWhoPosted(String nameOfPersonWhoPosted) {
        this.nameOfPersonWhoPosted = nameOfPersonWhoPosted;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getLikesCount() {
        return likesCount;
    }

    public void setLikesCount(int likesCount) {
        this.likesCount = likesCount;
    }

    public String[] getComments() {
        return comments;
    }

    public void setComments(String[] comments) {
        this.comments = comments;
    }

    public int getTimeOfPost() {
        return timeOfPost;
    }

    public void setTimeOfPost(int timeOfPost) {
        this.timeOfPost = timeOfPost;
    }

}

E - Exemple de fichier JSON: sampleJSONFile.json

Je viens de copier votre exemple JSON dans ce fichier et de le placer dans le dossier du projet.

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

F - Code de démonstration

package com.levo.jsonex;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.levo.jsonex.model.Page;
import com.levo.jsonex.model.PageInfo;
import com.levo.jsonex.model.Post;

public class JSONDemo {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            Page page = objectMapper.readValue(new File("sampleJSONFile.json"), Page.class);

            printParsedObject(page);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void printParsedObject(Page page) {
        printPageInfo(page.getPageInfo());
        System.out.println();
        printPosts(page.getPosts());
    }

    private static void printPageInfo(PageInfo pageInfo) {
        System.out.println("Page Info;");
        System.out.println("**********");
        System.out.println("\tPage Name : " + pageInfo.getPageName());
        System.out.println("\tPage Pic  : " + pageInfo.getPagePic());
    }

    private static void printPosts(Post[] posts) {
        System.out.println("Page Posts;");
        System.out.println("**********");
        for(Post post : posts) {
            printPost(post);
        }
    }

    private static void printPost(Post post) {
        System.out.println("\tPost Id                   : " + post.getPost_id());
        System.out.println("\tActor Id                  : " + post.getActor_id());
        System.out.println("\tPic Of Person Who Posted  : " + post.getPicOfPersonWhoPosted());
        System.out.println("\tName Of Person Who Posted : " + post.getNameOfPersonWhoPosted());
        System.out.println("\tMessage                   : " + post.getMessage());
        System.out.println("\tLikes Count               : " + post.getLikesCount());
        System.out.println("\tComments                  : " + Arrays.toString(post.getComments()));
        System.out.println("\tTime Of Post              : " + post.getTimeOfPost());
    }

}

G - Sortie de démonstration

Page Info;
****(*****
    Page Name : abc
    Page Pic  : http://example.com/content.jpg
Page Posts;
**********
    Post Id                   : 123456789012_123456789012
    Actor Id                  : 1234567890
    Pic Of Person Who Posted  : http://example.com/photo.jpg
    Name Of Person Who Posted : Jane Doe
    Message                   : Sounds cool. Can't wait to see it!
    Likes Count               : 2
    Comments                  : []
    Time Of Post              : 1234567890

26

Utilisez minimal-json qui est très rapide et facile à utiliser. Vous pouvez analyser à partir de String obj et Stream.

Exemples de données:

{
  "order": 4711,
  "items": [
    {
      "name": "NE555 Timer IC",
      "cat-id": "645723",
      "quantity": 10,
    },
    {
      "name": "LM358N OpAmp IC",
      "cat-id": "764525",
      "quantity": 2
    }
  ]
}

Analyse:

JsonObject object = Json.parse(input).asObject();
int orders = object.get("order").asInt();
JsonArray items = object.get("items").asArray();

Création de JSON:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Maven:

<dependency>
  <groupId>com.eclipsesource.minimal-json</groupId>
  <artifactId>minimal-json</artifactId>
  <version>0.9.4</version>
</dependency>

À quoi ressemblera le pojo?
Jesse

Pour Pojo, utilisez gson. Cette bibliothèque ne prend pas en charge.
Sakib Sami

22

Je pense que la meilleure pratique devrait être de passer par l' API Java JSON officielle qui est toujours en cours de réalisation.


7
Depuis que j'ai répondu, j'ai commencé à utiliser Jackson et je pense que c'est l'une des meilleures bibliothèques pour la désérialisation JSON.
Giovanni Botta

2
Pourquoi réutilisent-ils JSONP pour signifier quelque chose de différent de JSON avec Padding ? ...
Chris Wesseling

@ChrisWesseling Que voulez-vous dire?
Giovanni Botta

"API Java pour le traitement JSON (JSON-P)" est le titre du document auquel vous liez. Et cela m'a dérouté, car je savais que JSONP voulait dire autre chose.
Chris Wesseling

1
@ChrisWesseling oh c'est déroutant. C'est ce qu'ils ont choisi pour la spécification. Cependant, comme je l'ai dit, j'irais directement à Jackson.
Giovanni Botta

22

Puisque personne ne l'a encore mentionné, voici le début d'une solution utilisant Nashorn (partie d'exécution JavaScript de Java 8, mais déconseillée dans Java 11).

Solution

private static final String EXTRACTOR_SCRIPT =
    "var fun = function(raw) { " +
    "var json = JSON.parse(raw); " +
    "return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";

public void run() throws ScriptException, NoSuchMethodException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(EXTRACTOR_SCRIPT);
    Invocable invocable = (Invocable) engine;
    JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);
    result.values().forEach(e -> System.out.println(e));
}

Comparaison des performances

J'ai écrit du contenu JSON contenant trois tableaux de respectivement 20, 20 et 100 éléments. Je veux seulement obtenir les 100 éléments du troisième tableau. J'utilise la fonction JavaScript suivante pour analyser et obtenir mes entrées.

var fun = function(raw) {JSON.parse(raw).entries};

Exécuter l'appel un million de fois avec Nashorn prend 7,5 à 7,8 secondes

(JSObject) invocable.invokeFunction("fun", json);

org.json prend 20 ~ 21 secondes

new JSONObject(JSON).getJSONArray("entries");

Jackson prend 6,5 ~ 7 secondes

mapper.readValue(JSON, Entries.class).getEntries();

Dans ce cas, Jackson fonctionne mieux que Nashorn, qui est bien meilleur que org.json. L'API Nashorn est plus difficile à utiliser que org.json ou Jackson. Selon vos besoins, Jackson et Nashorn peuvent tous deux être des solutions viables.


1
Quelle est l'unité " ""? Pas pouces? C'est quelques secondes? Minutes?
Peter Mortensen

1
@PeterMortensen cela signifie secondes. Puisqu'il ne semble pas clair, je vais le changer. Merci pour l'examen.
otonglet

2
Malheureusement, Nashorn est obsolète dans Java 11. JEP 335 .
Par Mildner

1
Je sais que Nashorn est obsolète, mais j'ai aimé cette réponse parce que je ne voulais pas de dépendances; cependant, j'ai dû retravailler un peu l'exemple:ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval("var fun = function(raw) { return JSON.parse(raw); };"); Map<String, Object> json = (Map<String, Object>) ((Invocable) engine).invokeFunction("fun", jsonString);
kgibm

21

L'exemple ci-dessous montre comment lire le texte de la question, représenté par la variable "jsonText". Cette solution utilise Java EE7 de l'API (qui est mentionné dans certaines des autres réponses). La raison pour laquelle je l'ai ajouté comme réponse distincte est que le code suivant montre comment accéder réellement à certaines des valeurs affichées dans la question. Une implémentation de l'API javax.json serait nécessaire pour exécuter ce code. Le package complet pour chacune des classes requises a été inclus car je ne voulais pas déclarer les instructions "import".

javax.json.JsonReader jr = 
    javax.json.Json.createReader(new StringReader(jsonText));
javax.json.JsonObject jo = jr.readObject();

//Read the page info.
javax.json.JsonObject pageInfo = jo.getJsonObject("pageInfo");
System.out.println(pageInfo.getString("pageName"));

//Read the posts.
javax.json.JsonArray posts = jo.getJsonArray("posts");
//Read the first post.
javax.json.JsonObject post = posts.getJsonObject(0);
//Read the post_id field.
String postId = post.getString("post_id");

Maintenant, avant que quiconque ne note cette réponse car il n'utilise pas GSON, org.json, Jackson ou l'un des autres cadres tiers disponibles, c'est un exemple de "code requis" par la question pour analyser le texte fourni. Je suis bien conscient que l' adhésion à la norme actuelle JSR 353 n'était pas envisagée pour JDK 9 et en tant que telle, la spécification JSR 353 devrait être traitée de la même manière que toute autre implémentation de gestion JSON tierce.


15

Cela m'a époustouflé à quel point c'était facile. Vous pouvez simplement passer une Stringconservation de votre JSON au constructeur d'un JSONObject dans le package org.json par défaut.

JSONArray rootOfPage =  new JSONArray(JSONString);

Terminé. Goutte le microphone . Cela fonctionne JSONObjectsaussi avec . Après cela, vous pouvez simplement parcourir votre hiérarchie d' Objectsutilisation des get()méthodes sur vos objets.


13
Le JSONArraytype ne fait pas partie de l'API JD J2SE et vous ne dites pas quelle API ou bibliothèque tierce fournit ce type.
Bobulous

2
Non pas que je recommanderais de l'utiliser, mais je pense que cela fait référence au package "org.json" de json.org/java . Il était utilisé avant que de bonnes bibliothèques Java ne soient disponibles, mais c'était il y a des années (2008 ou avant)
StaxMan

1
Ou est-ce que brainmurphy1 signifie JSONArray dans Android?
Alexander Farber

12

Il existe de nombreuses bibliothèques JSON disponibles en Java.

Les plus connus sont: Jackson, GSON, Genson, FastJson et org.json.

Il y a généralement trois choses à considérer pour choisir une bibliothèque:

  1. Performance
  2. Facilité d'utilisation (le code est simple à écrire et lisible) - cela va de pair avec les fonctionnalités.
  3. Pour les applications mobiles: dépendance / taille du bocal

Spécifiquement pour les bibliothèques JSON (et toutes les bibliothèques de sérialisation / désérialisation), la liaison de données est également généralement intéressante car elle élimine le besoin d'écrire du code de plaque chauffante pour emballer / déballer les données.

Pour 1, voir ce benchmark: https://github.com/fabienrenaud/java-json-benchmark que j'ai fait en utilisant JMH qui compare (jackson, gson, genson, fastjson, org.json, jsonp) les performances des sérialiseurs et désérialiseurs en utilisant stream et API de liaison de données. Pour 2, vous pouvez trouver de nombreux exemples sur Internet. Le benchmark ci-dessus peut également être utilisé comme source d'exemples ...

Rapide point de repère: Jackson est 5 à 6 fois meilleur que org.json et plus de deux fois meilleur que GSON.

Pour votre exemple particulier, le code suivant décode votre json avec jackson:

public class MyObj {

    private PageInfo pageInfo;
    private List<Post> posts;

    static final class PageInfo {
        private String pageName;
        private String pagePic;
    }

    static final class Post {
        private String post_id;
        @JsonProperty("actor_id");
        private String actorId;
        @JsonProperty("picOfPersonWhoPosted")
        private String pictureOfPoster;
        @JsonProperty("nameOfPersonWhoPosted")
        private String nameOfPoster;
        private String likesCount;
        private List<String> comments;
        private String timeOfPost;
    }

    private static final ObjectMapper JACKSON = new ObjectMapper();
    public static void main(String[] args) throws IOException {
        MyObj o = JACKSON.readValue(args[0], MyObj.class); // assumes args[0] contains your json payload provided in your question.
    }
}

Faites moi savoir si vous avez des questions.


11

En plus d'autres réponses, je recommande ce service open source en ligne jsonschema2pojo.org pour la génération rapide de classes Java à partir de schémas json ou json pour GSON, Jackson 1.x ou Jackson 2.x. Par exemple, si vous avez:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": 1234567890,
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": 2,
              "comments": [],
              "timeOfPost": 1234567890
         }
    ]
}

Le jsonschema2pojo.org pour GSON a généré:

@Generated("org.jsonschema2pojo")
public class Container {
    @SerializedName("pageInfo")
    @Expose
    public PageInfo pageInfo;
    @SerializedName("posts")
    @Expose
    public List<Post> posts = new ArrayList<Post>();
}

@Generated("org.jsonschema2pojo")
public class PageInfo {
    @SerializedName("pageName")
    @Expose
    public String pageName;
    @SerializedName("pagePic")
    @Expose
    public String pagePic;
}

@Generated("org.jsonschema2pojo")
public class Post {
    @SerializedName("post_id")
    @Expose
    public String postId;
    @SerializedName("actor_id")
    @Expose
    public long actorId;
    @SerializedName("picOfPersonWhoPosted")
    @Expose
    public String picOfPersonWhoPosted;
    @SerializedName("nameOfPersonWhoPosted")
    @Expose
    public String nameOfPersonWhoPosted;
    @SerializedName("message")
    @Expose
    public String message;
    @SerializedName("likesCount")
    @Expose
    public long likesCount;
    @SerializedName("comments")
    @Expose
    public List<Object> comments = new ArrayList<Object>();
    @SerializedName("timeOfPost")
    @Expose
    public long timeOfPost;
}

9

Si vous avez une classe Java (disons Message) représentant la chaîne JSON (jsonString), vous pouvez utiliser la bibliothèque Jackson JSON avec:

Message message= new ObjectMapper().readValue(jsonString, Message.class);

et à partir de l'objet de message, vous pouvez récupérer n'importe lequel de ses attributs.


9

Gson est facile à apprendre et à mettre en œuvre, ce que nous devons savoir, ce sont deux méthodes

  • toJson () - Convertit un objet Java au format JSON

  • fromJson () - Convertit JSON en objet Java

"

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.google.gson.Gson;

public class GsonExample {
    public static void main(String[] args) {

    Gson gson = new Gson();

    try {

        BufferedReader br = new BufferedReader(
            new FileReader("c:\\file.json"));

        //convert the json string back to object
        DataObject obj = gson.fromJson(br, DataObject.class);

        System.out.println(obj);

    } catch (IOException e) {
        e.printStackTrace();
    }

    }
}

"


Pour une connaissance complète de Gson, reportez-vous aux liens ci-dessous. github.com/google/gson/blob/master/UserGuide.md
venkat

9

Il existe de nombreuses bibliothèques open source pour analyser le contenu JSON vers un objet ou simplement pour lire les valeurs JSON. Votre exigence est simplement de lire les valeurs et de les analyser en objet personnalisé. La bibliothèque org.json suffit donc dans votre cas.

Utilisez la bibliothèque org.json pour l'analyser et créer JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

Maintenant, utilisez cet objet pour obtenir vos valeurs:

String id = jsonObj.getString("pageInfo");

Vous pouvez voir un exemple complet ici:

Comment analyser JSON en Java


Il semble que toutes vos réponses contiennent un lien vers ce site. S'il s'agit de spam, veuillez arrêter. Si ce n'est pas le cas, désolé pour la confusion, mais je ne pense pas qu'il soit nécessaire de poster un lien dans toutes vos réponses.
Donald Duck

1
Il est difficile de donner une réponse, où vous pouvez expliquer tous les scénarios. Comme dans ce cas, comment lire un tableau json ou plusieurs objets json. Même si je le fais, la réponse serait très longue et la personne pourrait devenir confuse. Je donne donc un lien où une explication appropriée est donnée, avec un exemple approprié. Il peut choisir de visiter ou ne peut utiliser que mon explication.
lalitbhagtani

1
Il me semble que le lien que vous avez fourni ne montre que comment lire JSON. Où puis-je trouver des informations sur la façon de JSON?
Lampros Tzanetos

Désolé, mais je n'ai pas compris votre question: - "sur la façon de JSON aussi"
lalitbhagtani

7

Veuillez faire quelque chose comme ceci:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");

10
Euh, quelle bibliothèque est-ce?
Stewart

2
Je pense qu'il utilise org.json.simple
Lasitha Yapa

7

Vous pouvez utiliser la bibliothèque Gson pour analyser la chaîne JSON.

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonAsString, JsonObject.class);

String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString();
String pagePic = jsonObject.getAsJsonObject("pageInfo").get("pagePic").getAsString();
String postId = jsonObject.getAsJsonArray("posts").get(0).getAsJsonObject().get("post_id").getAsString();

Vous pouvez également parcourir le tableau "posts" comme suit:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}

5
{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

Java code :

JSONObject obj = new JSONObject(responsejsonobj);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......etc
}

9
Veuillez expliquer votre réponse car les réponses uniquement codées aident les autres beaucoup moins qu'un code bien documenté. Voir "donnez un poisson à un homme et vous le nourrissez pendant une journée; apprenez à un homme à pêcher et vous le nourrissez toute sa vie" .
Wai Ha Lee

Ce serait bien de mentionner que c'est pour «org.json» lib. Cependant, je ne pense pas que ce soit un bon moyen de le faire étant très verbeux, et la bibliothèque 'org.json' elle-même étant obsolète (API lente et encombrante). Il y a de meilleurs choix: GSON, Jackson, Boon, Genson à utiliser.
StaxMan

5

Lisez l'article de blog suivant, JSON en Java .

Ce message est un peu ancien, mais je veux quand même vous répondre.

Étape 1: créez une classe POJO de vos données.

Étape 2: Créez maintenant un objet à l'aide de JSON.

Employee employee = null;
ObjectMapper mapper = new ObjectMapper();
try{
    employee =  mapper.readValue(newFile("/home/sumit/employee.json"), Employee.class);
} 
catch (JsonGenerationException e){
    e.printStackTrace();
}

Pour plus d'informations, vous pouvez vous référer au lien suivant .


4

Les meilleures réponses sur cette page utilisent des exemples trop simples comme un objet avec une propriété (par exemple {nom: valeur}). Je pense que cet exemple encore simple mais réel peut aider quelqu'un.

Voici donc le JSON renvoyé par l'API Google Translate:

{
  "data": 
     {
        "translations": 
          [
            {
              "translatedText": "Arbeit"
             }
          ]
     }
}

Je veux récupérer la valeur de l'attribut "translationsText" par exemple "Arbeit" en utilisant Gson de Google.

Deux approches possibles:

  1. Récupérer un seul attribut nécessaire

    String json  = callToTranslateApi("work", "de");
    JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
    return jsonObject.get("data").getAsJsonObject()
            .get("translations").getAsJsonArray()
            .get(0).getAsJsonObject()
            .get("translatedText").getAsString();
  2. Créer un objet Java à partir de JSON

    class ApiResponse {
        Data data;      
        class Data {
            Translation[] translations;         
            class Translation {
                String translatedText;
            }
         }
     }

    ...

     Gson g = new Gson();
     String json =callToTranslateApi("work", "de");
     ApiResponse response = g.fromJson(json, ApiResponse.class);
     return response.data.translations[0].translatedText;

4

Vous devez d'abord sélectionner une bibliothèque d'implémentation pour ce faire.

L' API Java pour le traitement JSON (JSR 353) fournit des API portables pour analyser, générer, transformer et interroger JSON à l'aide du modèle d'objet et des API de streaming.

L' implémentation de référence est ici: https://jsonp.java.net/

Vous trouverez ici une liste des implémentations de JSR 353:

Quelles sont les API qui implémentent JSR-353 (JSON)

Et pour vous aider à décider ... J'ai aussi trouvé cet article:

http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

Si vous optez pour Jackson, voici un bon article sur la conversion entre JSON de / vers Java en utilisant Jackson: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- jackson /

J'espère que cela aide!


Vous pointez vers la version 1 de la bibliothèque Jackson. Suggère fortement d'utiliser la version actuelle de la bibliothèque Jackson.
Herbert Yu

4

Vous pouvez utiliser Jayway JsonPath . Vous trouverez ci-dessous un lien GitHub avec le code source, les détails du pom et une bonne documentation.

https://github.com/jayway/JsonPath

Veuillez suivre les étapes ci-dessous.

Étape 1 : Ajoutez la dépendance de chemin JSON JSON dans votre chemin de classe à l'aide de Maven ou téléchargez le fichier JAR et ajoutez-le manuellement.

<dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
</dependency>

Étape 2 : veuillez enregistrer votre JSON d'entrée sous forme de fichier pour cet exemple. Dans mon cas, j'ai enregistré votre JSON sous sampleJson.txt. Notez que vous avez manqué une virgule entre pageInfo et messages.

Étape 3 : Lisez le contenu JSON du fichier ci-dessus à l'aide de bufferedReader et enregistrez-le en tant que chaîne.

BufferedReader br = new BufferedReader(new FileReader("D:\\sampleJson.txt"));

        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
            sb.append(line);
            sb.append(System.lineSeparator());
            line = br.readLine();
        }
        br.close();
        String jsonInput = sb.toString();

Étape 4 : analyser votre chaîne JSON à l'aide de l'analyseur JAYway JSON.

Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonInput);

Étape 5 : Lisez les détails comme ci-dessous.

String pageName = JsonPath.read(document, "$.pageInfo.pageName");
String pagePic = JsonPath.read(document, "$.pageInfo.pagePic");
String post_id = JsonPath.read(document, "$.posts[0].post_id");

System.out.println("$.pageInfo.pageName " + pageName);
System.out.println("$.pageInfo.pagePic " + pagePic);
System.out.println("$.posts[0].post_id " + post_id);

La sortie sera :

$.pageInfo.pageName = abc
$.pageInfo.pagePic = http://example.com/content.jpg
$.posts[0].post_id  = 123456789012_123456789012

3

J'ai JSON comme ceci:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
}

Classe Java

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Code pour convertir ce JSON en classe Java.

    PageInfo pageInfo = JsonPath.parse(jsonString).read("$.pageInfo", PageInfo.class);

Maven

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
</dependency>

2

On peut utiliser l' annotation Apache @Model pour créer des classes de modèle Java représentant la structure des fichiers JSON et les utiliser pour accéder à divers éléments de l' arborescence JSON . Contrairement à d'autres solutions, celle-ci fonctionne complètement sans réflexion et convient donc aux environnements où la réflexion est impossible ou s'accompagne de frais généraux importants.

Il existe un exemple de projet Maven montrant l'utilisation. Tout d'abord, il définit la structure:

@Model(className="RepositoryInfo", properties = {
    @Property(name = "id", type = int.class),
    @Property(name = "name", type = String.class),
    @Property(name = "owner", type = Owner.class),
    @Property(name = "private", type = boolean.class),
})
final class RepositoryCntrl {
    @Model(className = "Owner", properties = {
        @Property(name = "login", type = String.class)
    })
    static final class OwnerCntrl {
    }
}

puis il utilise les classes RepositoryInfo et Owner générées pour analyser le flux d'entrée fourni et récupérer certaines informations tout en faisant cela:

List<RepositoryInfo> repositories = new ArrayList<>();
try (InputStream is = initializeStream(args)) {
    Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);
}

System.err.println("there is " + repositories.size() + " repositories");
repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {
    System.err.println("repository " + repo.getName() + 
        " is owned by " + repo.getOwner().getLogin()
    );
})

C'est ça! En plus de cela, voici un aperçu en direct montrant un exemple similaire avec une communication réseau asynchrone.


2

jsoniter(jsoniterator) est une bibliothèque json relativement nouvelle et simple, conçue pour être simple et rapide. Tout ce que vous devez faire pour désérialiser les données json est

JsonIterator.deserialize(jsonData, int[].class);

jsonDataest une chaîne de données json.

Consultez le site officiel pour plus d'informations.


1

Nous pouvons utiliser la classe JSONObject pour convertir une chaîne JSON en objet JSON et pour itérer sur l'objet JSON. Utilisez le code suivant.

JSONObject jObj = new JSONObject(contents.trim());
Iterator<?> keys = jObj.keys();

while( keys.hasNext() ) {
  String key = (String)keys.next();
  if ( jObj.get(key) instanceof JSONObject ) {           
    System.out.println(jObj.getString(String key));
  }
}

2
Ceci est uniquement Android
Ľubomír


1
@DermotCanniffe c'est juste Android.
user4020527

1

Vous pouvez utiliser la bibliothèque d'analyse de flux DSM pour analyser un document json et XML complexe. DSM analyse les données une seule fois et ne charge pas toutes les données en mémoire.

Disons que nous avons la classe Page pour désérialiser les données json données.

Classe de page

public class Page {
    private String pageName;
    private String pageImage;
    private List<Sting> postIds;

    // getter/setter

}

Créez un fichier de mappage yaml.

result:
  type: object     # result is array
  path: /posts
  fields:
    pageName:
        path: /pageInfo/pageName
    pageImage:
        path: /pageInfo/pagePic
    postIds:
      path: post_id
      type: array

Utilisez DSM pour extraire les champs.

DSM dsm=new DSMBuilder(new File("path-to-yaml-config.yaml")).create(Page.class);
Page page= (Page)dsm.toObject(new path-to-json-data.json");

variable de page sérialisée en json:

{
  "pageName" : "abc",
  "pageImage" : "http://example.com/content.jpg",
  "postIds" : [ "123456789012_123456789012" ]
}

DSM est très bon pour json et xml complexes.


0

Vous pouvez utiliser JsonNodepour une représentation arborescente structurée de votre chaîne JSON. Cela fait partie de la bibliothèque jackson rock solid qui est omniprésente.

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.