Jackson macht etwas wirklich Bizarres und ich kann keine Erklärung dafür finden. Ich mache polymorphe Serialisierung und es funktioniert perfekt, wenn ein Objekt für sich allein ist. Wenn Sie jedoch dasselbe Objekt in eine Liste einfügen und stattdessen die Liste serialisieren, wird die Typinformation gelöscht.
Die Tatsache, dass es Typinformationen verliert, würde zu einem Typlöschen führen. Dies geschieht jedoch während der Serialisierung des Inhalts der Liste; Alles, was Jackson tun muss, ist das aktuelle Objekt, das serialisiert wird, zu inspizieren, um seinen Typ zu bestimmen.
Ich habe ein Beispiel mit Jackson 2.5.1 erstellt:
%Vor%Hier ist die Ausgabe:
%Vor%Wie Sie sehen, fügt Jackson die Typinformationen nicht hinzu, wenn sich das Objekt in einer Liste befindet. Weiß jemand, warum das passiert?
Die verschiedenen Gründe, warum dies passiert, werden hier und hier . Ich stimme nicht unbedingt mit den Gründen überein, aber Jackson, wegen der Typauslöschung, kennt nicht die Art der Elemente List
enthält. Es wählt einen einfachen Serializer, der Ihre Anmerkungen nicht interpretiert.
Sie haben zwei Optionen in diesen Links vorgeschlagen:
Zunächst können Sie eine Klasse erstellen, die Collection
implementiert, sie instanziieren und die Instanz serialisieren.
Das Argument des generischen Typs Map
ist nicht verloren. Jackson hat Zugriff darauf und benutzt es.
Zweitens können Sie eine List<Cat>
für den Typ Cat
instanziieren und verwenden. Zum Beispiel
wird gedruckt
%Vor%Die Antwort, die Sotirios Delimanolis gab, ist die richtige. Ich dachte jedoch, es wäre nett, diese Problemumgehung als separate Antwort zu veröffentlichen. Wenn Sie sich in einer Umgebung befinden, in der Sie den ObjectMapper nicht für jede Art von Sache ändern können, die Sie zurückgeben müssen (wie eine Jersey / SpringMVC-Webanwendung), gibt es eine Alternative.
Sie können einfach ein privates abschließendes Feld in die Klasse einfügen, die den Typ enthält. Das Feld ist für nichts außerhalb der Klasse sichtbar, aber wenn Sie es mit @JsonProperty("@type")
(oder "@class" oder wie auch immer Ihr Typfeld benannt ist) annotieren, wird Jackson es unabhängig davon, wo sich das Objekt befindet, serialisieren.
Da Arrays keine Typlöschung verwenden, können Sie sie lösen, indem Sie die ObjectMapper.writeValueAsString
überschreiben, um die Sammlung in ein Array umzuwandeln.
Verwenden Sie es in Ihrem Test.main:
%Vor%Ausgabe (Katzen und Hunde Liste):
%Vor%Tags und Links java json serialization jackson