Analyse JSON à l'aide de Gson pour Java

154

Je voudrais analyser les données de JSON qui sont de type String. J'utilise Google Gson .

J'ai:

jsonLine = "
{
 "data": {
  "translations": [
   {
    "translatedText": "Hello world"
   }
  ]
 }
}
";

et ma classe est:

public class JsonParsing{

   public void parse(String jsonLine) {

      // there I would like to get String "Hello world"

   }

}
Martynas
la source

Réponses:

241

C'est du code simple pour le faire, j'ai évité toutes les vérifications mais c'est l'idée principale.

 public String parse(String jsonLine) {
    JsonElement jelement = new JsonParser().parse(jsonLine);
    JsonObject  jobject = jelement.getAsJsonObject();
    jobject = jobject.getAsJsonObject("data");
    JsonArray jarray = jobject.getAsJsonArray("translations");
    jobject = jarray.get(0).getAsJsonObject();
    String result = jobject.get("translatedText").getAsString();
    return result;
}

Pour rendre l'utilisation plus générique, vous constaterez que les javadocs de Gson sont assez clairs et utiles.

MByD
la source
1
JsonObject étend JsonElement, donc c'est les deux.
MByD
les lancements de première ligne ne peuvent pas instancier de type JsonParser sur la version gson-2.2.4.jar
Argument illégal
3
String result = jobject.get ("TranslatedText"). ToString (); Ces résultats comprendront les guillemets doubles. String result = jobject.get ("TranslatedText"). GetAsString (); n'inclut pas les citations.
user1165560
Est-ce que je suis le seul à penser que Gson complique les choses 98% du temps? Un simple JSONObject ferait l'affaire, mais nous détestons tous essayer / attraper autant?
tricknology
Je dois utiliser la classe parser, cependant, j'obtiens l'exception MalformedJsonException, donc je dois être capable de faire SetLeinient avec JsonParser. Comment?
Mason Wang
111

Dans ma première application gson, j'ai évité d'utiliser des classes supplémentaires pour attraper des valeurs principalement parce que j'utilise json pour les questions de configuration

malgré le manque d'informations (même la page gson), c'est ce que j'ai trouvé et utilisé:

a partir de

Map jsonJavaRootObject = new Gson().fromJson("{/*whatever your mega complex object*/}", Map.class)

Chaque fois que gson voit un {}, il crée une carte (en fait une StringMap gson)

Chaque fois que gson voit un «», il crée une chaîne

Chaque fois que gson voit un nombre, il crée un double

Chaque fois que gson voit un [], il crée une ArrayList

Vous pouvez utiliser ces faits (combinés) à votre avantage

Enfin c'est le code qui fait la chose

        Map<String, Object> javaRootMapObject = new Gson().fromJson(jsonLine, Map.class);

    System.out.println(
        (
            (Map)
            (
                (List)
                (
                    (Map)
                    (
                        javaRootMapObject.get("data")
                    )
                 ).get("translations")
            ).get(0)
        ).get("translatedText")
    );
Jorge Sanchez
la source
20

La chose la plus simple est généralement de créer une hiérarchie d'objets correspondante, comme ceci:

public class Wrapper {
   public Data data;
}
static class Data {
   public Translation[] translations;
}
static class Translation {
   public String translatedText;
}

puis liez à l'aide de GSON, traversez la hiérarchie d'objets via des champs. L'ajout de getters et de setters est inutile pour les conteneurs de données de base.

Donc quelque chose comme:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;
StaxMan
la source
2
Ensuite, votre structure d'objet ne correspond PAS à JSON.
StaxMan
8

Vous pouvez utiliser une classe distincte pour représenter l'objet JSON et utiliser des @SerializedNameannotations pour spécifier le nom de champ à saisir pour chaque membre de données:

public class Response {

   @SerializedName("data")
   private Data data;

   private static class Data {
      @SerializedName("translations")
      public Translation[] translations;
   }

   private static class Translation {
      @SerializedName("translatedText")
      public String translatedText;
   }

   public String getTranslatedText() {
      return data.translations[0].translatedText;
   }
}

Ensuite, vous pouvez faire l'analyse dans votre méthode parse () en utilisant un Gsonobjet:

Gson gson = new Gson();
Response response = gson.fromJson(jsonLine, Response.class);

System.out.println("Translated text: " + response.getTranslatedText());

Avec cette approche, vous pouvez réutiliser la Responseclasse pour ajouter d'autres champs supplémentaires pour récupérer d'autres membres de données que vous voudrez peut-être extraire de JSON - au cas où vous voudriez apporter des modifications pour obtenir des résultats, par exemple, pour plusieurs traductions en un seul appel, ou pour obtenir une chaîne supplémentaire pour la langue source détectée.

rmtheis
la source
7

Une façon serait de créer un JsonObject et d'itérer les paramètres. Par exemple

JsonObject jobj = new Gson().fromJson(jsonString, JsonObject.class);

Ensuite, vous pouvez extraire des valeurs de bean comme:

String fieldValue = jobj.get(fieldName).getAsString();
boolean fieldValue = jobj.get(fieldName).getAsBoolean();
int fieldValue = jobj.get(fieldName).getAsInt();

J'espère que cela t'aides.

Anand Tuli
la source
5

En utilisant Gson pour résoudre,
je créerais une classe pour un paramètre individuel dans la chaîne json. Vous pouvez également créer une classe principale appelée "Data", puis créer des classes internes de la même manière. J'ai créé des classes séparées pour plus de clarté.

Les classes sont les suivantes.

  • Les données
  • Traductions
  • TranslatedText

Dans la classe JsonParsing, nous appelons la méthode "parse" gson.fromJson(jsonLine, Data.class)qui convertira la chaîne en objets java en utilisant Reflection.

Une fois que nous avons accès à l'objet "Données", nous pouvons accéder à chaque paramètre individuellement.

Je n'ai pas eu l'occasion de tester ce code car je suis loin de ma machine de développement. Mais cela devrait aider.

Quelques bons exemples et articles.
http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html
http://sites.google.com/site/gson/gson-user-guide

Code

public class JsonParsing{

       public void parse(String jsonLine) {

           Gson gson = new GsonBuilder().create();
           Data data = gson.fromJson(jsonLine, Data.class);

           Translations translations = data.getTranslation();
           TranslatedText[] arrayTranslatedText = translations.getArrayTranslatedText(); //this returns an array, based on json string

           for(TranslatedText translatedText:arrayTranslatedText )
           {
                  System.out.println(translatedText.getArrayTranslatedText());
           }
       }

    }


    public class Data{
           private  Translations translations;
          public Translations getTranslation()
          {
             return translations;
          }

          public void setTranslation(Translations translations)
           {
                  this.translations = translations;
           }
    }

    public class Translations
    {
        private  TranslatedText[] translatedText;
         public TranslatedText[] getArrayTranslatedText()
         {
             return translatedText;
         }

           public void setTranslatedText(TranslatedText[] translatedText)
           {
                  this.translatedText= translatedText;
           }
    }

    public class TranslatedText
    {
        private String translatedText;
        public String getTranslatedText()
        {
           return translatedText;
        }

        public void setTranslatedText(String translatedText)
        {
           this.translatedText = translatedText;
        }
    }
Kensen John
la source
N'avez-vous pas besoin de setters pour ces classes d'aide? Rien ne peut définir le private String translatedTextsans violer le contrôle d'accès, il n'y a donc aucun moyen de le fromJSONdéfinir dans les JVM qui n'ont pas opté pour le piétinement par réflexion partout dans le contrôle d'accès.
Mike Samuel
@Mike Samuel tire complètement oublié les Setters
Kensen John
3
    JsonParser parser = new JsonParser();
    JsonObject jo = (JsonObject) parser.parse(data);
    JsonElement je = jo.get("some_array");

    //Parsing back the string as Array
    JsonArray ja = (JsonArray) parser.parse(o.get("some_array").getAsString());
    for (JsonElement jo : ja) {
    JsonObject j = (JsonObject) jo;
        // Your Code, Access json elements as j.get("some_element")
    }

Un exemple simple pour analyser un JSON comme celui-ci

{"some_array": "[\" some_element \ ": 1, \" some_more_element \ ": 2]", "some_other_element": 3}

Rahul Malhotra
la source
2

Tout d'abord, générez Getter et Setter en utilisant le site d'analyse ci-dessous

http://www.jsonschema2pojo.org/

Maintenant, utilisez Gson

GettetSetterClass object=new Gson().fromjson(jsonLine,GettetSetterClass.class);

Maintenant, utilisez object pour obtenir des valeurs telles que des données, translationText

Nilesh Panchal
la source
2

Vous pouvez utiliser une requête JsonPath pour extraire la valeur. Et avec JsonSurfer qui est soutenu par Gson, votre problème peut être résolu par simplement deux lignes de code!

    JsonSurfer jsonSurfer = JsonSurfer.gson();
    String result = jsonSurfer.collectOne(jsonLine, String.class, "$.data.translations[0].translatedText");
Leo Wang
la source
1

Code d'une ligne:

System.out.println(new Gson().fromJson(jsonLine,JsonObject.class).getAsJsonObject().get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString());
retArdos
la source