Ich benutze JAVA 1.6 und Jackson 1.9.9. Ich habe eine Aufzählung
public enum Event {
FORGOT_PASSWORD("forgot password");
private final String value;
private Event(final String description) {
this.value = description;
}
@JsonValue
final String value() {
return this.value;
}
}
Ich habe einen @JsonValue hinzugefügt. Dies scheint den Job zu erledigen, in den das Objekt serialisiert wird:
{"event":"forgot password"}
aber wenn ich versuche zu deserialisieren, bekomme ich eine
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.globalrelay.gas.appsjson.authportal.Event from String value 'forgot password': value not one of declared Enum instance names
Was fehlt mir hier?
java
enums
jackson
jsonserializer
Pookieman
quelle
quelle
{"Event":"FORGOT_PASSWORD"}
? Beachten Sie die Obergrenzen für Event und FORGOT_PASSWORD.getValue
diesGetValue
nicht funktioniertAntworten:
Die von @xbakesx aufgeführte Serializer / Deserializer-Lösung eignet sich hervorragend, wenn Sie Ihre Enum- Klasse vollständig von ihrer JSON-Darstellung entkoppeln möchten .
Wenn Sie eine in sich geschlossene Lösung bevorzugen, ist alternativ eine Implementierung basierend auf
@JsonCreator
und@JsonValue
Anmerkungen bequemer.Wenn Sie also das Beispiel von @Stanley nutzen, ist Folgendes eine vollständige, in sich geschlossene Lösung (Java 6, Jackson 1.9):
quelle
Beachten Sie, dass Sie ab diesem Commit im Juni 2015 (Jackson 2.6.2 und höher) einfach schreiben können:
quelle
Sie sollten eine statische Factory-Methode erstellen, die ein einzelnes Argument verwendet und mit Anmerkungen versehen
@JsonCreator
(verfügbar seit Jackson 1.2).Lesen Sie mehr über JsonCreator Anmerkung hier .
quelle
@JSONValue
zu serialisieren und@JSONCreator
zu deserialisieren.@JsonCreator public static Event valueOf(int intValue) { ... }
int
zumEvent
Enumerator deserialisieren .Aktuelle Antwort:
Der Standard-Deserializer für Aufzählungen wird
.name()
zum Deserialisieren verwendet, daher wird der nicht verwendet@JsonValue
. Wie @OldCurmudgeon hervorhob, müssten Sie übergeben{"event": "FORGOT_PASSWORD"}
, um dem.name()
Wert zu entsprechen.Eine andere Option (vorausgesetzt, Sie möchten, dass die json-Werte für Schreiben und Lesen gleich sind) ...
Mehr Info:
Es gibt (noch) eine andere Möglichkeit, den Serialisierungs- und Deserialisierungsprozess mit Jackson zu verwalten. Sie können diese Anmerkungen angeben, um Ihren eigenen benutzerdefinierten Serializer und Deserializer zu verwenden:
Dann muss man schreiben
MySerializer
undMyDeserializer
welche so aussehen:MySerializer
MyDeserializer
Das letzte bisschen, insbesondere um dies mit einer Aufzählung zu tun
JsonEnum
, die mit der MethodegetYourValue()
serialisiert wird, könnte Ihr Serializer und Deserializer folgendermaßen aussehen:quelle
Ich habe eine sehr schöne und prägnante Lösung gefunden, die besonders nützlich ist, wenn Sie die Enum-Klassen nicht wie in meinem Fall ändern können. Anschließend sollten Sie einen benutzerdefinierten ObjectMapper mit einer bestimmten aktivierten Funktion bereitstellen. Diese Funktionen sind seit Jackson 1.6 verfügbar. Sie müssen also nur die
toString()
Methode in Ihre Aufzählung schreiben .Weitere enumbezogene Funktionen sind verfügbar, siehe hier:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
quelle
Versuche dies.
quelle
Sie können die Deserialisierung für jedes Attribut anpassen.
Deklarieren Sie Ihre Deserialize-Klasse mit der AnnotationJsonDeserialize (
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
) für das Attribut, das verarbeitet wird. Wenn dies eine Aufzählung ist:Auf diese Weise wird Ihre Klasse verwendet, um das Attribut zu deserialisieren. Dies ist ein vollständiges Beispiel:
quelle
Es gibt verschiedene Ansätze, mit denen Sie die Deserialisierung eines JSON-Objekts in eine Aufzählung durchführen können. Mein Lieblingsstil ist es, eine innere Klasse zu bilden:
quelle
Hier ist ein weiteres Beispiel, das Zeichenfolgenwerte anstelle einer Karte verwendet.
quelle
Im Kontext einer Aufzählung
@JsonValue
funktioniert die Verwendung von now (seit 2.0) für die Serialisierung und Deserialisierung.Nach den Jackson-Annotations Javadoc für
@JsonValue
:Die
Event
Annotation der Aufzählung wie oben funktioniert also (sowohl für die Serialisierung als auch für die Deserialisierung) mit Jackson 2.0+.quelle
Neben @JsonSerialize @JsonDeserialize können Sie im Object Mapper auch SerializationFeature und DeserializationFeature (Jackson-Bindung) verwenden.
Beispiel: DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, die den Standardaufzählungstyp angeben, wenn der angegebene nicht in der Aufzählungsklasse definiert ist.
quelle
Der einfachste Weg, den ich gefunden habe, ist die Verwendung der Annotation @ JsonFormat.Shape.OBJECT für die Aufzählung.
quelle
In meinem Fall hat dies Folgendes gelöst:
Serialisiert und deserialisiert den folgenden JSON:
Ich hoffe, es hilft!
quelle