Ich habe eine JSON-Zeichenfolge, die ich in die folgende Klasse deSerialisieren sollte
class Data <T> {
int found;
Class<T> hits
}
Wie mache ich es? Dies ist der übliche Weg
mapper.readValue(jsonString, Data.class);
Aber wie erwähne ich, wofür T steht?
Antworten:
Sie müssen
TypeReference
für jeden generischen Typ, den Sie verwenden , ein Objekt erstellen und dieses für die Deserialisierung verwenden. Zum Beispiel -quelle
Data<T>
, das ist KEIN Typ. Sie müssen die tatsächliche Klasse angeben. sonst ist es dasselbe wieData<Object>
.TypeReference
? ist escom.fasterxml.jackson.core.type
?Sie können das nicht tun: Sie müssen einen vollständig aufgelösten Typ wie angeben
Data<MyType>
.T
ist nur eine Variable und ebenso bedeutungslos.Aber wenn Sie meinen, dass
T
dies bekannt sein wird, nur nicht statisch, müssen Sie ein Äquivalent vonTypeReference
dynamisch erstellen . Andere Fragen, auf die verwiesen wird, erwähnen dies möglicherweise bereits, aber es sollte ungefähr so aussehen:quelle
TypeReference
:return mapper.readValue(json, clazz);
Was genau ist das Problem hier?TypeFactory
.. Ich werde meine Antwort bearbeiten.Als erstes serialisieren Sie, dann können Sie deserialisieren.
Wenn Sie also serialisieren, sollten Sie verwenden
@JsonTypeInfo
, damit Jackson Klasseninformationen in Ihre JSON-Daten schreibt. Was Sie tun können, ist wie folgt:Wenn Sie dann deserialisieren, werden Sie feststellen, dass Jackson Ihre Daten in eine Klasse deserialisiert hat, die Ihre Variablen tatsächlich zur Laufzeit treffen.
quelle
Für Klassendaten <>
quelle
Schreiben Sie einfach eine statische Methode in die Util-Klasse. Ich lese einen Json aus einer Datei. Sie können String auch readValue geben
Verwendung:
quelle
Sie können es in eine andere Klasse einschließen, die den Typ Ihres generischen Typs kennt.
Z.B,
Hier ist etwas ein konkreter Typ. Sie benötigen einen Wrapper pro reifiziertem Typ. Ansonsten weiß Jackson nicht, welche Objekte er erstellen soll.
quelle
JSON-Zeichenfolgen, die deserialisiert werden müssen, müssen die Typinformationen zu Parametern enthalten
T
.Sie werden Jackson Anmerkungen müssen auf jeder Klasse setzen , die als Parameter übergeben werden können ,
T
in der Klasse ,Data
so dass die Art Informationen über ParametertypT
können von / zu JSON - String von Jackson geschrieben gelesen werden.Nehmen wir an, dass
T
dies jede Klasse sein kann, die die abstrakte Klasse erweitertResult
.Sobald jede Klasse (oder ihr gemeinsamer Supertyp), die als Parameter übergeben werden kann, mit
T
Anmerkungen versehen ist, wird Jackson Informationen zu ParameternT
in den JSON aufnehmen. Ein solcher JSON kann dann deserialisiert werden, ohne den ParameterT
zur Kompilierungszeit zu kennen.Dieser Jackson-Dokumentationslink befasst sich mit polymorpher Deserialisierung, ist aber auch für diese Frage nützlich.
quelle
Ab Jackson 2.5 ist eine elegante Methode zur Lösung dieses Problems die Verwendung der TypeFactory.constructParametricType-Methode (Class parametrized, Class ... parameterClasses) , mit der ein Jackson
JavaType
durch Angabe der parametrisierten Klasse und ihrer parametrisierten Typen direkt definiert werden kann.Angenommen, Sie möchten deserialisieren
Data<String>
, können Sie Folgendes tun:Beachten Sie, dass es nicht wirklich schwieriger wäre, wenn die Klasse mehrere parametrisierte Typen deklarieren würde:
Wir könnten :
quelle
quelle
Wenn Sie Scala verwenden und den generischen Typ zur Kompilierungszeit kennen, TypeReference jedoch nicht überall in all Ihren API-Anwendern manuell übergeben möchten, können Sie den folgenden Code verwenden (mit Jackson 2.9.5):
die so verwendet werden kann:
quelle
Um eine generische JSON-Zeichenfolge mit Jackson in ein Java-Objekt zu deserialisieren, benötigen Sie:
So definieren Sie eine JSON-Klasse
Führen Sie eine Attributzuordnung durch.
Endgültiger Code, getestet und einsatzbereit:
Wichtig:
@JsonAnySetter
Annotation ist obligatorisch und gewährleistet eine generische JSON-Analyse und -Population.Für kompliziertere Fälle mit verschachtelten Arrays lesen Sie bitte die Baeldung-Referenz: https://www.baeldung.com/jackson-mapping-dynamic-object
quelle
Beispiel für eine nicht sehr gute, aber einfache Entscheidung (nicht nur für Jackson, sondern auch für Spring RestTemplate usw.):
quelle