JSON розбирає за допомогою Gson для Java


154

Я хотів би проаналізувати дані типу JSON, який має тип String. Я використовую Google Gson .

У мене є:

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

і мій клас:

public class JsonParsing{

   public void parse(String jsonLine) {

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

   }

}

Відповіді:


241

Це простий код, щоб зробити це, я уникав усіх перевірок, але це головна ідея.

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

Щоб зробити використання більш загальним - ви побачите, що javadocs Gson досить чіткі та корисні.


1
JsonObject розширює JsonElement, тож це і те, і інше.
MByD

кидки першого рядка не можуть створити екземпляр типу JsonParser у версії gson-2.2.4.jar
Незаконний аргумент

3
String result = jobject.get ("перекладеноText"). ToString (); Ці результати включатимуть подвійні лапки. String result = jobject.get ("перекладеноText"). GetAsString (); не включає цитати.
користувач1165560

Я єдиний, хто думає, що Гсон надмірно ускладнює речі в 98% часу? Простий JSONObject зробив би, але ми всі ненавидимо спробувати / зловити стільки?
хитрологія

Мені потрібно використовувати клас парсера, однак я отримую MalformedJsonException, тому мені потрібно мати змогу зробити SetLeinient з JsonParser. Як?
Мейсон Ван

111

У моєму першому додатку gson я уникав використання додаткових класів для лову значень, головним чином тому, що я використовую json для питань конфігурації

незважаючи на брак інформації (навіть на сторінці gson), саме це я знайшов і використав:

починаючи з

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

Щоразу, коли gson бачить {}, він створює Map (насправді gson StringMap)

Щоразу, коли gson бачить '', він створює String

Щоразу, коли gson бачить число, він створює Double

Кожен раз, коли gson бачить [], він створює ArrayList

Ви можете використовувати ці факти (комбіновані) на вашу користь

Нарешті, це код, який робить річ

        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

Найпростіше, як правило, створити відповідну ієрархію об'єктів, наприклад:

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

а потім пов'язувати за допомогою GSON, ієрархію обхідних об'єктів через поля. Додавання геттерів і сетерів безглуздо для базових контейнерів даних.

Тож щось на кшталт:

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

2
Тоді ваша об’єктна структура НЕ відповідає JSON.
StaxMan


8

Ви можете використовувати окремий клас для представлення об'єкта JSON і використовувати @SerializedNameпримітки для визначення імені поля для захоплення для кожного члена даних:

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

Тоді ви можете зробити розбір у вашому методі parse (), використовуючи a Gson об'єкт:

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

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

При такому підході ви можете повторно використовувати Responseклас для додавання будь-яких інших додаткових полів, щоб забрати інших членів даних, які ви хочете отримати з JSON - якщо ви хочете внести зміни, щоб отримати результати для, скажімо, декількох перекладів за один дзвінок, або отримати додатковий рядок для виявленої мови джерела.


7

Одним із способів було б створити JsonObject і ітерацію за допомогою параметрів. Наприклад

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

Тоді ви можете отримати значення квасолі, наприклад:

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

Сподіваюся, це допомагає.


5

Використовуючи Gson для вирішення,
я створив би клас для індивідуального параметра в рядку json. Крім того, ви можете створити один основний клас під назвою "Дані", а потім створити внутрішні класи аналогічно. Я створив окремі класи для наочності.

Заняття такі.

  • Дані
  • Переклади
  • TranslatedText

У класі JsonParsing ми називаємо метод "parse", gson.fromJson(jsonLine, Data.class)який перетворить String в java-об'єкти за допомогою Reflection.

Отримавши доступ до об'єкта "Дані", ми можемо отримати доступ до кожного параметра окремо.

Не отримав шансу перевірити цей код, оскільки я перебуваю далеко від своєї розроблювальної машини. Але це має допомогти.

Кілька хороших прикладів та статей.
http://albertattard.blogspot.com/2009/06/practical-example-of-gson.html
http://sites.google.com/site/gson/gson-user-guide

Код

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

Вам не потрібні якісь сетери на цих курсах помічників? Ніщо не може встановити private String translatedTextбез порушення контролю доступу, тому немає способу fromJSONвстановити це у JVM, які не включили відображення, що топчуть весь контроль доступу.
Майк Самуель

@ Майк Семюель Стріл повністю забув про сеттерів
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")
    }

Простий приклад для розбору подібного JSON

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


2

По-перше, генеруйте Getter і Setter, використовуючи сайт для аналізу нижче

http://www.jsonschema2pojo.org/

Тепер використовуйте Gson

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

Тепер використовуйте об'єкт для отримання таких значень, як дані, translationText


2

Для отримання значення можна використовувати запит JsonPath. А з JsonSurfer, який підтримується Gson, вашу проблему можна вирішити просто двома рядками коду!

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

1

Код рядка:

System.out.println(new Gson().fromJson(jsonLine,JsonObject.class).getAsJsonObject().get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString());
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.