Parsowanie tablicy JSON do java.util.List za pomocą Gson

119

Mam JsonObjectnazwisko "mapping"z następującą zawartością:

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

Wiem, że mogę uzyskać tablicę "servers"z:

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

A teraz chcę to przeanalizować JsonArrayw java.util.List...

Jaki jest najłatwiejszy sposób na zrobienie tego?

Abel Callejo
źródło
2
@ruakh Jest wiele różnic między tym pytaniem a tym pytaniem. Ten dotyczy Gson.
Abel Callejo
@AbelMelquiadesCallejo spójrz na odpowiedź, mam nadzieję, że rozwiąże Twój problem.
Prateek
@ruakh yes Zgadzam się z tobą i znam JsonArraynarzędzia Iterable. Po prostu znajduję nowe sposoby, inne niż dodawanie nowej biblioteki.
Abel Callejo

Odpowiedzi:

273

Zdecydowanie najłatwiejszym sposobem jest użycie domyślnej funkcji analizującej Gson fromJson().

Istnieje implementacja tej funkcji , która jest odpowiednia, gdy trzeba przeprowadzić deserializację do dowolnego ParameterizedType(np. Dowolnego List), czyli fromJson(JsonElement json, Type typeOfT).

W twoim przypadku wystarczy pobrać Typez a, List<String>a następnie przeanalizować tablicę JSON na to Type, na przykład:

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

W twoim przypadku yourJsonjest to JsonElement, ale może to być również a String, any Readerlub a JsonReader.

Możesz zajrzeć do dokumentacji API Gson .

MikO
źródło
7
Typemożna znaleźć w jakim opakowaniu?
Abel Callejo
10
Typeto wbudowany interfejs Java znajdujący się w pakieciejava.lang.reflect
MikO
Musiałem użyć getString()zamiast get()albo .fromJson()narzekać.
lenooh
@MikO Mam podobne pytanie do Gson tutaj . Chciałem zobaczyć, czy możesz mi pomóc. Mam rozwiązanie, ale problem polega na tym, że wygląda to bardzo niechlujnie, aby przeanalizować JSON w Mapie.
Jan
18

Poniższy kod używa com.google.gson.JsonArray. Wydrukowałem liczbę elementów na liście, a także elementy na liście

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

}

WYNIK

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]
Prateek
źródło
8

Przeczytałem rozwiązanie z oficjalnej strony Gson tutaj

A ten kod dla Ciebie:

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

Wynik wyświetlany na monitorze:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1
Hoang
źródło
ta sama odpowiedź jak powyżej - nadal przy użyciu metody statycznejnew Gson().fromJson()
Abel Callejo
cóż, mój problem był inny, ale twój fragment rozwiązał mój problem. Zapisałem listę ciągów, ale chcę pobrać ciągi. Następnie twój fragment przypomnij mi ich klasę String []., Którą mogę umieścić w celu pobrania danych. Dziękuję
badarshahzad
2

Udało mi się zmusić mapowanie listy do pracy przy użyciu tylko @SerializedNamedla wszystkich pól ... nie Typebyła potrzebna żadna logika .

Uruchamiając kod - w kroku 4 poniżej - poprzez debugger jestem w stanie zaobserwować, że List<ContentImage> mGalleryImagesobiekt zapełnił się danymi JSON

Oto przykład:

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. Klasa Java z listą

public class FocusArea {

    @SerializedName("name")
    private String mName;

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

3. Klasa Java dla elementów listy

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4. Kod Java, który przetwarza JSON

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }
Gene Bo
źródło
0

Biorąc pod uwagę, że zaczynasz mapping.get("servers").getAsJsonArray(), jeśli masz dostęp do guawy Streams , możesz wykonać poniższą jedną linijkę:

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

Notatka StreamSupportnie będzie w stanie pracować nad JsonElementczcionką, więc jest ona niewystarczająca.

Alex Moore-Niemi
źródło