JSON-Analyse mit Gson für Java


154

Ich möchte Daten von JSON analysieren, die vom Typ sind String. Ich benutze Google Gson .

Ich habe:

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

und meine Klasse ist:

public class JsonParsing{

   public void parse(String jsonLine) {

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

   }

}

Antworten:


241

Dies ist ein einfacher Code, ich habe alle Überprüfungen vermieden, aber das ist die Hauptidee.

 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;
}

Um die Verwendung allgemeiner zu gestalten, werden Sie feststellen, dass Gsons Javadocs ziemlich klar und hilfreich sind.


1
JsonObject erweitert JsonElement, also ist es beides.
MByD

Die ersten Zeilenwürfe können nicht vom Typ JsonParser in Version gson-2.2.4.jar
Illegal Argument

3
String result = jobject.get ("translateText"). ToString (); Diese Ergebnisse enthalten doppelte Anführungszeichen. String result = jobject.get ("translateText"). GetAsString (); enthält keine Anführungszeichen.
user1165560

Al ich der einzige, der denkt, dass Gson die Dinge 98% der Zeit überkompliziert? Ein einfaches JSONObject würde reichen, aber wir alle hassen es, so viel zu versuchen / zu fangen?
Tricknologie

Ich muss die Parser-Klasse verwenden, erhalte jedoch die MalformedJsonException, sodass ich SetLeinient mit JsonParser ausführen kann. Wie?
Mason Wang

111

In meiner ersten gson-Anwendung habe ich die Verwendung zusätzlicher Klassen zum Abfangen von Werten vermieden, hauptsächlich weil ich json für Konfigurationsangelegenheiten verwende

Trotz des Mangels an Informationen (sogar der Gson-Seite) habe ich Folgendes gefunden und verwendet:

ab

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

Jedes Mal, wenn gson ein {} sieht, wird eine Map erstellt (tatsächlich eine gson StringMap).

Jedes Mal, wenn gson ein '' sieht, wird ein String erstellt

Jedes Mal, wenn gson eine Zahl sieht, wird ein Double erstellt

Jedes Mal, wenn gson ein [] sieht, wird eine ArrayList erstellt

Sie können diese Fakten (kombiniert) zu Ihrem Vorteil nutzen

Schließlich ist dies der Code, der das Ding macht

        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")
    );

20

Am einfachsten ist es normalerweise, eine passende Objekthierarchie zu erstellen, wie folgt:

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

und dann mit GSON binden, Objekthierarchie über Felder durchlaufen. Das Hinzufügen von Gettern und Setzern ist für grundlegende Datencontainer sinnlos.

Also so etwas wie:

Wrapper value = GSON.fromJSON(jsonString, Wrapper.class);
String text = value.data.translations[0].translatedText;

2
Dann stimmt Ihre Objektstruktur NICHT mit JSON überein.
StaxMan


8

Sie können eine separate Klasse verwenden, um das JSON-Objekt darzustellen, und mithilfe von @SerializedNameAnmerkungen den Feldnamen angeben, der für jedes Datenelement erfasst werden soll:

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;
   }
}

Anschließend können Sie die Analyse in Ihrer parse () -Methode mithilfe eines GsonObjekts durchführen:

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

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

Mit diesem Ansatz können Sie die ResponseKlasse wiederverwenden , um weitere zusätzliche Felder hinzuzufügen, um andere Datenelemente aufzunehmen, die Sie möglicherweise aus JSON extrahieren möchten. oder um eine zusätzliche Zeichenfolge für die erkannte Quellsprache zu erhalten.


7

Eine Möglichkeit wäre, ein JsonObject zu erstellen und die Parameter zu durchlaufen. Beispielsweise

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

Dann können Sie Bean-Werte wie folgt extrahieren:

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

Hoffe das hilft.


5

Mit Gson zum Lösen
würde ich eine Klasse für einzelne Parameter im json-String erstellen. Alternativ können Sie eine Hauptklasse mit dem Namen "Daten" erstellen und dann auf ähnliche Weise innere Klassen erstellen. Ich habe aus Gründen der Übersichtlichkeit separate Klassen erstellt.

Die Klassen sind wie folgt.

  • Daten
  • Übersetzungen
  • Übersetzter Text

In der Klasse JsonParsing rufen wir die Methode "parse" gson.fromJson(jsonLine, Data.class)auf, die den String in Java-Objekten mit Reflection konvertiert.

Sobald wir Zugriff auf das Objekt "Daten" haben, können wir auf jeden Parameter einzeln zugreifen.

Ich hatte keine Gelegenheit, diesen Code zu testen, da ich nicht auf meiner Entwicklungsmaschine bin. Das sollte aber helfen.

Einige gute Beispiele und Artikel.
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;
        }
    }

Benötigen Sie keine Setter für diese Hilfsklassen? Nichts kann das einstellen, private String translatedTextohne die Zugriffskontrolle zu verletzen, daher gibt es keine Möglichkeit fromJSON, es in JVMs einzustellen, die sich nicht für Reflexions-Trampling über die gesamte Zugriffskontrolle entschieden haben.
Mike Samuel

@ Mike Samuel Shoot völlig vergessen die Setter
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")
    }

Ein einfaches Beispiel, um einen JSON wie diesen zu analysieren

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


2

Generieren Sie zunächst Getter And Setter mithilfe der folgenden Parsing-Site

http://www.jsonschema2pojo.org/

Verwenden Sie jetzt Gson

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

Verwenden Sie nun object, um Werte wie data, translationText abzurufen


2

Sie können eine JsonPath-Abfrage verwenden, um den Wert zu extrahieren. Und mit JsonSurfer, das von Gson unterstützt wird, kann Ihr Problem durch einfach zwei Codezeilen gelöst werden!

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

1

Ein Zeilencode:

System.out.println(new Gson().fromJson(jsonLine,JsonObject.class).getAsJsonObject().get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString());
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.