Proszę o dane z serwera, który zwraca dane w formacie JSON. Rzutowanie HashMap na JSON podczas wysyłania żądania wcale nie było trudne, ale w drugą stronę wydaje się trochę trudne. Odpowiedź JSON wygląda następująco:
{
"header" : {
"alerts" : [
{
"AlertID" : "2",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
},
{
"AlertID" : "3",
"TSExpires" : null,
"Target" : "1",
"Text" : "woot",
"Type" : "1"
}
],
"session" : "0bc8d0835f93ac3ebbf11560b2c5be9a"
},
"result" : "4be26bc400d3c"
}
W jaki sposób najłatwiej byłoby uzyskać dostęp do tych danych? Używam modułu GSON.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
współpracuje z gson 2.6.2.Odpowiedzi:
Proszę bardzo:
źródło
TypeToken
- to niejawne rzucanie w środku.{"k1":"apple","k2":"orange"}
Ten kod działa:
źródło
Map<String, Object>
ponieważ jeśli Json to nie tylko łańcuchy, pojawia się błądTypeToken
.Wiem, że jest to dość stare pytanie, ale szukałem rozwiązania, aby ogólnie dokonać deserializacji zagnieżdżonego JSON do
Map<String, Object>
i nic nie znalazłem.Sposób, w jaki działa mój deserializator yaml, domyślnie ustawia obiekty JSON na
Map<String, Object>
gdy nie określisz typu, ale wydaje się, że gson tego nie robi. Na szczęście możesz to zrobić za pomocą niestandardowego deserializatora.Użyłem następujący Deserializator naturalnie deserializowania niczego, zalegających
JsonObject
SMap<String, Object>
iJsonArray
S,Object[]
S, gdzie wszystkie dzieci są podobnie deserializacji.Bałagan w środku
handlePrimitive
metodzie ma na celu upewnienie się, że zawsze otrzymujesz tylko Double, Integer lub Long, i prawdopodobnie może być lepszy, lub przynajmniej uproszczony, jeśli nie masz nic przeciwko otrzymywaniu BigDecimals, co moim zdaniem jest domyślne.Możesz zarejestrować ten adapter jak:
A potem nazwij to tak:
Nie jestem pewien, dlaczego nie jest to domyślne zachowanie w gson, ponieważ jest ono w większości innych częściowo ustrukturyzowanych bibliotek serializacji ...
źródło
Z Google Gson 2.7 (prawdopodobnie również wcześniejszymi wersjami, ale testowałem z bieżącą wersją 2.7) jest tak prosty, jak:
Który zwraca
Map
typcom.google.gson.internal.LinkedTreeMap
i działa rekurencyjnie na zagnieżdżone obiekty, tablice itp.Uruchomiłem przykład OP (tak po prostu zastąpiłem double- pojedynczymi cudzysłowami i usunąłem białe znaki):
I otrzymałem następujące dane wyjściowe:
źródło
Aktualizacja dla nowej biblioteki Gson:
Możesz teraz parsować zagnieżdżonego Jsona do mapy, ale powinieneś być ostrożny na wypadek, gdybyś spróbował parsować Jsona, aby
Map<String, Object>
wpisać: spowoduje to wyjątek. Aby to naprawić, po prostu zadeklaruj wynik jakoLinkedTreeMap
typ. Przykład poniżej:źródło
Map<String,Object> result = gson.fromJson(json , Map.class);
. Korzystanie z gson 2.6.2.Miałem dokładnie to samo pytanie i znalazłem się tutaj. Miałem inne podejście, które wydaje się znacznie prostsze (może nowsze wersje gson?).
z następującym jsonem
Następujące
wyjścia
Możesz dynamicznie sprawdzać za pomocą instanceof podczas nawigacji swoim jsonObject. Coś jak
To działa dla mnie, więc musi działać dla ciebie ;-)
źródło
Poniżej obsługiwane jest od gson 2.8.0
źródło
Spróbuj, to zadziała. Użyłem go do Hashtable .
Zamień KioskStatusResource na klasę i liczbę całkowitą na klasę kluczową.
źródło
Oto, czego używałem:
źródło
Oto linijka, która to zrobi:
źródło
new TypeToken<HashMap<String, Object>>(){}
stworzy nową wewnętrznąRozwiązałem podobny problem z niestandardowym JsonDeSerializer. Starałem się, aby było to trochę ogólne, ale wciąż za mało. Jest to jednak rozwiązanie, które odpowiada moim potrzebom.
Przede wszystkim musisz wdrożyć nowy JsonDeserializer dla obiektów mapy.
Metoda deserializacji będzie wyglądać podobnie do tej:
Wadą tego rozwiązania jest to, że klucz mojej mapy jest zawsze typu „Ciąg”. Jednak zmieniając niektóre rzeczy, ktoś może uczynić to ogólnym. Ponadto muszę powiedzieć, że klasa wartości powinna zostać przekazana do konstruktora. Więc metoda
getMyType()
w moim kodzie zwraca typ wartości mapy, który został przekazany w konstruktorze.Możesz odnieść się do tego postu Jak napisać niestandardowy deserializator JSON dla Gson? aby dowiedzieć się więcej o niestandardowych deserializatorach.
źródło
Zamiast tego możesz użyć tej klasy :) (obsługuje nawet listy, listy zagnieżdżone i json)
Aby przekonwertować ciąg JSON na skrót, użyj tego:
źródło
To bardziej dodatek do odpowiedzi Kevina Dolana niż pełna odpowiedź, ale miałem problem z wyodrębnieniem tego typu z liczby. To jest moje rozwiązanie:
źródło
źródło
JSONObject zwykle używa
HashMap
wewnętrznie do przechowywania danych. Możesz więc użyć go jako mapy w swoim kodzie.Przykład,
źródło
Użyłem tego kodu:
źródło