Разбор массива JSON в java.util.List с помощью Gson

119

У меня есть JsonObjectимя "mapping"со следующим содержанием:

{
    "client": "127.0.0.1",
    "servers": [
        "8.8.8.8",
        "8.8.4.4",
        "156.154.70.1",
        "156.154.71.1"
    ]
}

Я знаю, что могу получить массив "servers"с помощью:

mapping.get("servers").getAsJsonArray()

А теперь я хочу разобрать это JsonArrayна java.util.List...

Как это сделать проще всего?

Абель Кальехо
источник
2
@ruakh, между тем и этим вопросом много различий. Этот имеет дело с Gson.
Abel Callejo
@AbelMelquiadesCallejo, посмотрите ответ. Надеюсь, он решит вашу проблему.
Prateek
@ruakh да , я согласен с вами , и я знаю , что JsonArrayорудия Iterable. Просто я также нахожу новые способы, помимо добавления новой библиотеки.
Abel Callejo

Ответы:

273

Определенно, самый простой способ сделать это - использовать функцию синтаксического анализа Gson по умолчанию fromJson().

Существует реализация этой функции, подходящая для случаев, когда вам нужно десериализовать в любой ParameterizedType(например, любой List), то есть fromJson(JsonElement json, Type typeOfT).

В вашем случае вам просто нужно получить Typeиз a, List<String>а затем проанализировать массив JSON в нем Type, например:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

В вашем случае yourJsonэто a JsonElement, но это также может быть a String, any Readerили a JsonReader.

Вы можете взглянуть на документацию Gson API .

Мико
источник
8
Typeв каком пакете можно найти?
Abel Callejo
10
Type- это встроенный интерфейс Java, расположенный в пакетеjava.lang.reflect
MikO
Я должен был использовать getString()вместо, get()иначе .fromJson()жаловался.
lenooh
@MikO У меня есть аналогичный вопрос с Gson здесь . Я хотел посмотреть, сможете ли вы мне помочь. У меня есть решение, но проблема в том, что просто проанализировать JSON на карте выглядит очень беспорядочно.
Джон
18

Ниже используется код com.google.gson.JsonArray. Я напечатал количество элементов в списке, а также элементы в списке

import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


public class Test {

    static String str = "{ "+ 
            "\"client\":\"127.0.0.1\"," + 
            "\"servers\":[" + 
            "    \"8.8.8.8\"," + 
            "    \"8.8.4.4\"," + 
            "    \"156.154.70.1\"," + 
            "    \"156.154.71.1\" " + 
            "    ]" + 
            "}";

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            JsonParser jsonParser = new JsonParser();
            JsonObject jo = (JsonObject)jsonParser.parse(str);
            JsonArray jsonArr = jo.getAsJsonArray("servers");
            //jsonArr.
            Gson googleJson = new Gson();
            ArrayList jsonObjList = googleJson.fromJson(jsonArr, ArrayList.class);
            System.out.println("List size is : "+jsonObjList.size());
                    System.out.println("List Elements are  : "+jsonObjList.toString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

ВЫВОД

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]
Prateek
источник
8

Я прочитал решение с официального сайта Gson здесь

И этот код для вас:

    String json = "{"client":"127.0.0.1","servers":["8.8.8.8","8.8.4.4","156.154.70.1","156.154.71.1"]}";

    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
    JsonArray jsonArray = jsonObject.getAsJsonArray("servers");

    String[] arrName = new Gson().fromJson(jsonArray, String[].class);

    List<String> lstName = new ArrayList<>();
    lstName = Arrays.asList(arrName);

    for (String str : lstName) {
        System.out.println(str);
    }    

Результат показать на мониторе:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1
Хоанг
источник
тот же ответ, что и выше - все еще использующий статический методnew Gson().fromJson()
Абель
ну, моя проблема была другой, но ваш фрагмент решил мою проблему. Я сохранил список строк, но хочу получить строки. Затем ваш фрагмент напоминает мне об их классе String []. Для извлечения данных. Спасибо
badarshahzad 01
2

Мне удалось получить отображение списка для работы, просто используя @SerializedNameдля всех полей ... никакой логики Typeне требовалось.

Запустив код - на шаге 4 ниже - через отладчик, я могу заметить, что List<ContentImage> mGalleryImagesобъект заполнен данными JSON

Вот пример:

1. JSON

   {
    "name": "Some House",
    "gallery": [
      {
        "description": "Nice 300sqft. den.jpg",
        "photo_url": "image/den.jpg"
      },
      {
        "description": "Floor Plan",
        "photo_url": "image/floor_plan.jpg"
      }
    ]
  }

2. Класс Java со списком

public class FocusArea {

    @SerializedName("name")
    private String mName;

    @SerializedName("gallery")
    private List<ContentImage> mGalleryImages;
}

3. Класс Java для элементов списка.

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. Код Java, обрабатывающий JSON.

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }
Джин Бо
источник
0

Если вы начинаете с того mapping.get("servers").getAsJsonArray(), что у вас есть доступ к Guava Streams , вы можете сделать следующий однострочник:

List<String> servers = Streams.stream(jsonArray.iterator())
                              .map(je -> je.getAsString())
                              .collect(Collectors.toList());

Заметка StreamSupportне сможет работать с JsonElementтипом, поэтому этого недостаточно.

Алекс Мур-Ниеми
источник