Wie rufe ich den Standard-Deserializer von einem benutzerdefinierten Deserializer in Jackson auf
Ich habe ein problem in meinem custom-deserializer in Jackson. Ich möchte den Zugriff auf die Standard-Serialisierung zum Auffüllen der Objekt bin ich zu Deserialisieren. Nachdem die Bevölkerung ich werde tun, einige benutzerdefinierte Sachen, aber zuerst will ich zu Deserialisieren das Objekt mit dem Standard-jackson-Verhalten.
Dies ist der code, den ich im moment haben.
public class UserEventDeserializer extends StdDeserializer<User> {
private static final long serialVersionUID = 7923585097068641765L;
public UserEventDeserializer() {
super(User.class);
}
@Override
@Transactional
public User deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
User deserializedUser = null;
deserializedUser = super.deserialize(jp, ctxt, new User());
//The previous line generates an exception java.lang.UnsupportedOperationException
//Because there is no implementation of the deserializer.
//I want a way to access the default spring deserializer for my User class.
//How can I do that?
//Special logic
return deserializedUser;
}
}
Was ich brauche ist eine Methode zum initialisieren der default-deserializer, so dass ich vorab ausfüllen, meine POJO, bevor ich meine Besondere Logik.
Beim Aufruf Deserialisieren von innerhalb der benutzerdefinierten deserializer Es Nahten die Methode wird aufgerufen, aus dem aktuellen Kontext keine Rolle, wie Baue ich die serializer-Klasse. Wegen der Anmerkung in mein POJO. Dies bewirkt, dass ein Stack-Overflow-exception aus offensichtlichen Gründen. Ich habe versucht, die Initialisierung einer beandeserializer aber der Prozess ist sehr Komplex und ich habe es nicht geschafft den richtigen Weg zu finden, es zu tun. Ich habe auch versucht, eine überlastung des annotation-introspector-ohne Erfolg, dachte, es könnte mir helfen, ignorieren Sie die Anmerkung in der DeserializerContext. Schließlich Nähte ich haben könnte, hatte einigen Erfolg mit JsonDeserializerBuilders obwohl dies von mir verlangt zu tun, einige Magische Sachen zu bekommen ahold von der application-Kontext von spring. Ich würde schätzen, dass jede Sache, die dazu führen könnten, dass mir eine saubere Lösung zum Beispiel wie Kann ich konstruiere eine Deserialisierung Kontext Lesen, ohne die JsonDeserializer annotation.
InformationsquelleAutor der Frage Pablo Jomer | 2013-08-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als StaxMan schon vorgeschlagen, Sie können dies tun, indem Sie ein
BeanDeserializerModifier
und registrieren Sie ihn überSimpleModule
. Das folgende Beispiel sollte funktionieren:InformationsquelleAutor der Antwort schummar
Gibt es paar Möglichkeiten, dies zu tun, aber um es richtig zu machen, beinhaltet etwas mehr Arbeit. Im Grunde können Sie nicht mit sub-classing, da die Informationen Standard deserializers brauchen, ist gebaut von Klassendefinitionen.
Also, was können Sie wahrscheinlich verwenden, ist die Errichtung einer
BeanDeserializerModifier
registrieren, dass überModule
interface (verwendenSimpleModule
). Sie brauchen, um zu definieren/überschreibenmodifyDeserializer
und für den speziellen Fall, wo Sie wollen, um Ihre eigene Logik (bei dem Typ entspricht), bauen Ihre eigenen deserializer, übergeben Sie die Standard-deserializer, die Sie gegeben sind.Und dann in
deserialize()
Methode können Sie nur delegieren, rufen, nehmen Sie das Ergebnis-Objekt.Alternativ, wenn Sie tatsächlich erstellen und füllen das Objekt, können Sie dies tun und rufen überladene version von
deserialize()
nimmt, dass Dritte argument; Objekt zu Deserialisieren.Andere Möglichkeit, die funktionieren könnte (aber nicht 100% sicher) würde angeben
Converter
Objekt (@JsonDeserialize(converter=MyConverter.class)
). Dies ist eine neue Jackson 2.2 feature.In Ihrem Fall, Konverter würde eigentlich nicht konvertieren Typ, aber Sie vereinfachen das Objekt ändern: aber ich weiß nicht, wenn, würden Sie genau das tun, was Sie wollen, da die Standard-deserializer würde zuerst aufgerufen werden, und erst dann werden Ihre
Converter
.InformationsquelleAutor der Antwort StaxMan
Wenn es möglich ist, für Sie zu erklären, zusätzliche Benutzer-Klasse und implementieren Sie können es nur mit Anmerkungen
InformationsquelleAutor der Antwort Bill
Den
DeserializationContext
hat einereadValue()
Methode, die Sie verwenden können. Diese Arbeit sollte für sowohl die Standard-deserializer und alle benutzerdefinierten deserializers Sie haben.Nur sicher sein, rufen Sie
traverse()
auf dieJsonNode
Ebene, die Sie Lesen möchten, zum abrufen derJsonParser
übergebenreadValue()
.InformationsquelleAutor der Antwort Derek Cochran
Eine einfachere Lösung für mich war einfach eine andere Bohne von
ObjectMapper
verwenden, um Deserialisieren das Objekt (Dank https://stackoverflow.com/users/1032167/varren Kommentar) - in meinem Fall war ich interessiert, entweder zu Deserialisieren, um seine id (int) oder das ganze Objekt https://stackoverflow.com/a/46618193/986160für jede Entität, die benötigt werden, gehen durch die benutzerdefinierte deserializer, die wir brauchen, um es zu konfigurieren in der globalen
ObjectMapper
bean in der Spring-Boot-Anwendung in meinem Fall (e.g fürCategory
):InformationsquelleAutor der Antwort Michail Michailidis
Ich war nicht ok mit
BeanSerializerModifier
da es die Kräfte zu erklären, einige Verhaltens-änderungen in zentralenObjectMapper
anstatt in benutzerdefinierten deserializer selbst und in der Tat ist die parallele Lösung für die Markierung der entity-Klasse, mitJsonSerialize
. Wenn Sie fühlen, dass es die ähnliche Art und Weise, Sie schätzen könnte meine Antwort hier: https://stackoverflow.com/a/43213463/653539InformationsquelleAutor der Antwort Tomáš Záluský
Entlang der Linien von dem, was Tomáš Záluský vorgeschlagen hat in den Fällen, in denen die Verwendung von
BeanDeserializerModifier
unerwünscht ist, können Sie konstruieren eine Standard-deserializer selbst mitBeanDeserializerFactory
obwohl es gibt einige zusätzliche Einrichtung erforderlich. Im Kontext dieser Lösung würde dann ungefähr so Aussehen:InformationsquelleAutor der Antwort hopper