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?



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 .


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]

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

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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.