Ich fordere Daten von einem Server an, der Daten im JSON-Format zurückgibt. Das Casting einer HashMap in JSON beim Erstellen der Anfrage war überhaupt nicht schwierig, aber der andere Weg scheint etwas schwierig zu sein. Die JSON-Antwort sieht folgendermaßen aus:
{
"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"
}
Wie kann man am einfachsten auf diese Daten zugreifen? Ich benutze das GSON-Modul.
Map<String,Object> result = new Gson().fromJson(json, Map.class);
funktioniert mit gson 2.6.2.Antworten:
Bitte schön:
quelle
TypeToken
es nicht gerne - es impliziert implizites Casting im Inneren.{"k1":"apple","k2":"orange"}
Dieser Code funktioniert:
quelle
Map<String, Object>
denn wenn der JSON nicht nur Zeichenfolgen ist, erhalten Sie eine FehlermeldungTypeToken
.Ich weiß, dass dies eine ziemlich alte Frage ist, aber ich suchte nach einer Lösung, um verschachtelten JSON generisch in a zu deserialisieren
Map<String, Object>
, und fand nichts.So wie mein yaml-Deserializer funktioniert, werden JSON-Objekte standardmäßig verwendet,
Map<String, Object>
wenn Sie keinen Typ angeben, aber gson scheint dies nicht zu tun. Glücklicherweise können Sie dies mit einem benutzerdefinierten Deserializer erreichen.Ich habe den folgenden Deserializer verwendet, um alles auf natürliche Weise zu deserialisieren, wobei standardmäßig
JsonObject
s bis sMap<String, Object>
undJsonArray
s bisObject[]
s verwendet werden, wobei alle Kinder auf ähnliche Weise deserialisiert werden.Die Unordnung in der
handlePrimitive
Methode besteht darin, sicherzustellen, dass Sie immer nur ein Double oder ein Integer oder ein Long erhalten und wahrscheinlich besser oder zumindest vereinfacht sein könnten, wenn Sie mit BigDecimals einverstanden sind, was meiner Meinung nach die Standardeinstellung ist.Sie können diesen Adapter wie folgt registrieren:
Und dann nenne es wie:
Ich bin mir nicht sicher, warum dies nicht das Standardverhalten in gson ist, da es in den meisten anderen halbstrukturierten Serialisierungsbibliotheken vorkommt ...
quelle
Mit Googles Gson 2.7 (wahrscheinlich auch frühere Versionen, aber ich habe mit der aktuellen Version 2.7 getestet) ist es so einfach wie:
Dies gibt einen
Map
Typ zurückcom.google.gson.internal.LinkedTreeMap
und funktioniert rekursiv für verschachtelte Objekte, Arrays usw.Ich habe das OP-Beispiel so ausgeführt (einfach doppelt durch einfache Anführungszeichen ersetzt und Leerzeichen entfernt):
Und bekam die folgende Ausgabe:
quelle
Update für neue Gson-Bibliothek:
Sie können verschachtelte Json jetzt direkt in Map analysieren. Sie sollten sich jedoch bewusst sein, falls Sie versuchen, Json nach
Map<String, Object>
Typ zu analysieren : Es wird eine Ausnahme ausgelöst . Um dies zu beheben, deklarieren Sie einfach das Ergebnis alsLinkedTreeMap
Typ. Beispiel unten:quelle
Map<String,Object> result = gson.fromJson(json , Map.class);
. Verwenden von gson 2.6.2.Ich hatte genau die gleiche Frage und bin hier gelandet. Ich hatte einen anderen Ansatz, der viel einfacher zu sein scheint (vielleicht neuere Versionen von gson?).
mit dem folgenden json
Folgende
Ausgänge
Sie können beim Navigieren in Ihrem jsonObject mithilfe von instanceof dynamisch überprüfen. Etwas wie
Es funktioniert für mich, also muss es für dich funktionieren ;-)
quelle
Unten wird seit gson 2.8.0 unterstützt
quelle
Versuchen Sie dies, es wird funktionieren. Ich habe es für Hashtable verwendet .
Ersetzen Sie KioskStatusResource durch Ihre Klasse und Integer durch Ihre Schlüsselklasse.
quelle
Folgendes habe ich verwendet:
quelle
Hier ist ein Einzeiler, der es schafft:
quelle
new TypeToken<HashMap<String, Object>>(){}
eine neue Inline-Unterklasse erstellt wird und alle Linters zumindest eine Warnung auslösen werdenIch habe ein ähnliches Problem mit einem benutzerdefinierten JsonDeSerializer behoben. Ich habe versucht, es ein bisschen generisch zu machen, aber immer noch nicht genug. Es ist jedoch eine Lösung, die meinen Bedürfnissen entspricht.
Zunächst müssen Sie einen neuen JsonDeserializer für Kartenobjekte implementieren.
Und die Deserialisierungsmethode sieht ungefähr so aus:
Der Nachteil dieser Lösung ist, dass der Schlüssel meiner Karte immer vom Typ "String" ist. Wenn man jedoch einige Dinge ändert, kann jemand sie generisch machen. Außerdem muss ich sagen, dass die Klasse des Wertes im Konstruktor übergeben werden sollte. Die Methode
getMyType()
in meinem Code gibt also den Typ der Map-Werte zurück, der im Konstruktor übergeben wurde.Sie können auf diesen Beitrag verweisen. Wie schreibe ich einen benutzerdefinierten JSON-Deserializer für Gson? um mehr über benutzerdefinierte Deserialisierer zu erfahren.
quelle
Sie können diese Klasse stattdessen verwenden :) (behandelt gerade Listen, verschachtelte Listen und JSON)
Verwenden Sie Folgendes, um Ihre JSON-Zeichenfolge in eine Hashmap zu konvertieren :
quelle
Dies ist eher ein Nachtrag zu Kevin Dolans Antwort als eine vollständige Antwort, aber ich hatte Probleme, den Typ aus der Zahl zu extrahieren. Das ist meine Lösung:
quelle
quelle
JSONObject wird normalerweise
HashMap
intern zum Speichern der Daten verwendet. Sie können es also als Karte in Ihrem Code verwenden.Beispiel,
quelle
Ich habe diesen Code verwendet:
quelle