Розбиття масиву 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а, 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є JsonElement, але це також може бути String, будь-яке Readerчи а JsonReader.

Ви можете ознайомитись із документацією щодо API Gson .


7
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]

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 []. Class для отримання даних. Дякую
badarshahzad

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типом, тому її недостатньо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.