Разбор 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"

   }

}
Martynas
источник
Аналогично: stackoverflow.com/questions/4110664/…
Вадим

Ответы:

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 Гсона довольно понятны и полезны.

MByD
источник
1
JsonObject расширяет JsonElement, так что это оба.
MByD
в первой строке не может быть создан экземпляр типа JsonParser в версии gson-2.2.4.jar
аргумент
3
String result = jobject.get ("translationText"). ToString (); Этот результат будет включать двойные кавычки. String result = jobject.get ("translationText"). GetAsString (); не включает в себя кавычки.
user1165560
Я единственный, кто думает, что Гсон усложняет вещи в 98% случаев? Подойдет простой JSONObject, но мы все так ненавидим try / catch?
трикология
Мне нужно использовать класс синтаксического анализатора, однако я получаю исключение MalformedJsonException, поэтому я должен иметь возможность выполнять SetLeinient с JsonParser. Как?
Мейсон Ван
111

В моем первом приложении gson я избегал использования дополнительных классов для перехвата значений, потому что я использую json для настройки

несмотря на недостаток информации (даже страницы gson), я нашел и использовал ее:

начиная с

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

Каждый раз, когда gson видит {}, он создает карту (на самом деле StringMap gson)

Каждый раз, когда gson видит '', он создает строку

Каждый раз, когда гсон видит число, он создает двойной

Каждый раз, когда 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;
StaxMan
источник
2
Тогда ваша объектная структура НЕ соответствует JSON.
StaxMan
14

Вы можете создать соответствующие классы Java для объектов JSON. Целочисленные, строковые значения могут отображаться как есть. Json может быть разобран так

Gson gson = new GsonBuilder().create(); 
Response r = gson.fromJson(jsonString, Response.class);

Вот пример - http://rowsandcolumns.blogspot.com/2013/02/url-encode-http-get-solr-request-and.html

blue01
источник
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 (), используя Gsonобъект:

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

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

При таком подходе вы можете повторно использовать Responseкласс для добавления любых других дополнительных полей, чтобы выбрать другие элементы данных, которые вы, возможно, захотите извлечь из JSON - в случае, если вы хотите внести изменения, чтобы получить результаты, скажем, для нескольких переводов за один вызов, или получить дополнительную строку для обнаруженного исходного языка.

rmtheis
источник
7

Одним из способов будет создание JsonObject и итерация по параметрам. Например

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

Затем вы можете извлечь значения bean-компонентов:

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, которые не включили отражение, попирающее контроль доступа.
Майк Сэмюэль
@ Майк Сэмюэл снимал, совершенно забыл про сеттеров
Кенсен Джон
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 And Setter, используя нижеприведенный сайт

http://www.jsonschema2pojo.org/

Теперь используйте Gson

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

Теперь используйте объект для получения таких значений, как data, 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());
retArdos
источник