Używam JAVA 1.6 i Jackson 1.9.9 Mam wyliczenie
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;
}
}
Dodałem @JsonValue, wydaje się, że wykonuje to zadanie, w którym serializuje obiekt do:
{"event":"forgot password"}
ale kiedy próbuję deserializować, dostaję
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
Czego tu brakuje?
java
enums
jackson
jsonserializer
pookieman
źródło
źródło
{"Event":"FORGOT_PASSWORD"}
? Zwróć uwagę na ograniczenia zarówno dla zdarzenia, jak i FORGOT_PASSWORD.getValue
tegoGetValue
nie działaOdpowiedzi:
Rozwiązanie szeregujące / deserializujące wskazane przez @xbakesx jest doskonałe, jeśli chcesz całkowicie oddzielić swoją klasę enum od jej reprezentacji JSON.
Alternatywnie, jeśli wolisz samodzielne rozwiązanie, wygodniejsze byłoby wdrożenie oparte na adnotacjach
@JsonCreator
i@JsonValue
adnotacjach.Tak więc korzystając z przykładu @Stanley, poniższe jest kompletnym samodzielnym rozwiązaniem (Java 6, Jackson 1.9):
źródło
Zauważ, że od tego zatwierdzenia w czerwcu 2015 r. (Jackson 2.6.2 i wyżej) możesz teraz po prostu napisać:
źródło
Powinieneś stworzyć statyczną metodę fabryczną, która pobiera pojedynczy argument i adnotuje go
@JsonCreator
(dostępna od Jackson 1.2)Przeczytaj więcej o adnotacjach JsonCreator tutaj .
źródło
@JSONValue
serializować i@JSONCreator
deserializować.@JsonCreator public static Event valueOf(int intValue) { ... }
deserializacjiint
doEvent
wyliczający.Rzeczywista odpowiedź:
Domyślny deserializator dla wyliczeń używa
.name()
do deserializacji, więc nie używa@JsonValue
. Tak jak wskazał @OldCurmudgeon, musisz przekazać,{"event": "FORGOT_PASSWORD"}
aby dopasować.name()
wartość.Inna opcja (zakładając, że chcesz, aby zapis i odczyt wartości Json były takie same) ...
Więcej informacji:
Istnieje (jeszcze) inny sposób zarządzania procesem serializacji i deserializacji z Jacksonem. Możesz określić te adnotacje, aby użyć własnego niestandardowego serializatora i deserializatora:
Następnie musisz napisać
MySerializer
iMyDeserializer
które wyglądają tak:MySerializer
MyDeserializer
Na
JsonEnum
koniec , szczególnie w przypadku wyliczenia szeregowego za pomocą metodygetYourValue()
, Twój serializator i deserializator mogą wyglądać następująco:źródło
Znalazłem bardzo miłe i zwięzłe rozwiązanie, szczególnie przydatne, gdy nie możesz modyfikować klas enum, jak to było w moim przypadku. Następnie powinieneś dostarczyć niestandardowy ObjectMapper z włączoną określoną funkcją. Te funkcje są dostępne od wersji Jackson 1.6. Musisz tylko napisać
toString()
metodę w swoim wyliczeniu.Dostępnych jest więcej funkcji związanych z wyliczaniem, patrz tutaj:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
źródło
Spróbuj tego.
źródło
Możesz dostosować deserializację dla dowolnego atrybutu.
Zadeklaruj swoją deserializowaną klasę za pomocą adnotacjiJsonDeserialize (
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
) dla atrybutu, który zostanie przetworzony. Jeśli jest to Enum:W ten sposób twoja klasa zostanie wykorzystana do deserializacji atrybutu. To jest pełny przykład:
źródło
Istnieją różne podejścia do deserializacji obiektu JSON do wyliczenia. Moim ulubionym stylem jest stworzenie klasy wewnętrznej:
źródło
Oto kolejny przykład, który używa wartości ciągu zamiast mapy.
źródło
W kontekście wyliczenia użycie
@JsonValue
teraz (od 2.0) działa na serializacji i deserializacji.Według javadoc jackson-adnotations dla
@JsonValue
:Tak więc
Event
wyliczanie adumacji tak jak powyżej działa (zarówno w przypadku serializacji, jak i deserializacji) z jacksonem 2.0+.źródło
Oprócz używania @JsonSerialize @JsonDeserialize, możesz również użyć SerializationFeature i DeserializationFeature (powiązanie Jacksona) w maperze obiektów.
Takie jak DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, które dają domyślny typ wyliczenia, jeśli podany nie jest zdefiniowany w klasie wyliczania.
źródło
Najprostszym sposobem, jaki znalazłem, jest użycie adumacji @ JsonFormat.Shape.OBJECT dla wyliczenia.
źródło
W moim przypadku to rozwiązało:
Serializuje i deserializuje następujący plik Json:
Mam nadzieję, że to pomoże!
źródło