Saya menggunakan JAVA 1.6 dan Jackson 1.9.9 Saya mendapat enum
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;
}
}
Saya telah menambahkan @JsonValue, ini tampaknya melakukan pekerjaan yang membuat serialisasi objek menjadi:
{"event":"forgot password"}
tetapi ketika saya mencoba deserialize saya mendapatkan
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
Apa yang kulewatkan di sini?
java
enums
jackson
jsonserializer
pookieman
sumber
sumber
{"Event":"FORGOT_PASSWORD"}
? Perhatikan batas pada Event dan FORGOT_PASSWORD.getValue
iniGetValue
tidak bekerjaJawaban:
Solusi serializer / deserializer yang ditunjukkan oleh @xbakesx adalah solusi yang sangat baik jika Anda ingin memisahkan kelas enum Anda dari representasi JSON.
Atau, jika Anda lebih suka solusi mandiri, implementasi berdasarkan
@JsonCreator
dan@JsonValue
anotasi akan lebih nyaman.Jadi memanfaatkan contoh oleh @Stanley berikut ini adalah solusi lengkap mandiri (Java 6, Jackson 1.9):
sumber
Perhatikan bahwa pada komit ini pada Juni 2015 (Jackson 2.6.2 dan lebih tinggi) Anda sekarang dapat menulis:
sumber
Anda harus membuat metode pabrik statis yang mengambil argumen tunggal dan menjelaskannya dengan
@JsonCreator
(tersedia sejak Jackson 1.2)Baca lebih lanjut tentang anotasi JsonCreator di sini .
sumber
@JSONValue
untuk membuat cerita bersambung dan@JSONCreator
deserialize.@JsonCreator public static Event valueOf(int intValue) { ... }
deserializeint
keEvent
enumerator.Jawaban Aktual:
Deserializer default untuk enums digunakan
.name()
untuk deserialize, jadi itu tidak menggunakan@JsonValue
. Jadi seperti yang ditunjukkan oleh @OldCurmudgeon, Anda harus masuk{"event": "FORGOT_PASSWORD"}
untuk mencocokkan.name()
nilainya.Opsi lain (dengan asumsi Anda ingin nilai tulis dan baca json sama) ...
Info lebih lanjut:
Ada (belum) cara lain untuk mengelola proses serialisasi dan deserialisasi dengan Jackson. Anda dapat menentukan anotasi ini untuk menggunakan serializer dan deserializer kustom Anda sendiri:
Maka Anda harus menulis
MySerializer
danMyDeserializer
yang terlihat seperti ini:MySerializer
MyDeserializer
Sedikit terakhir, terutama untuk melakukan ini pada enum
JsonEnum
yang membuat serial dengan metode inigetYourValue()
, serializer dan deserializer Anda mungkin terlihat seperti ini:sumber
Saya telah menemukan solusi yang sangat bagus dan ringkas, terutama berguna ketika Anda tidak dapat memodifikasi kelas enum seperti dalam kasus saya. Maka Anda harus menyediakan ObjectMapper kustom dengan fitur tertentu yang diaktifkan. Fitur-fitur tersebut tersedia sejak Jackson 1.6. Jadi Anda hanya perlu menulis
toString()
metode di enum Anda.Ada lebih banyak fitur terkait enum yang tersedia, lihat di sini:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
sumber
Coba ini.
sumber
Anda dapat menyesuaikan deserialization untuk atribut apa pun.
Deklarasikan kelas deserialize Anda menggunakan annotationJsonDeserialize (
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
) untuk atribut yang akan diproses. Jika ini adalah Enum:Dengan cara ini kelas Anda akan digunakan untuk menghapus atribut tersebut. Ini adalah contoh lengkap:
sumber
Ada berbagai pendekatan yang dapat Anda lakukan untuk melakukan deserialisasi objek JSON ke enum. Gaya favorit saya adalah membuat kelas dalam:
sumber
Berikut adalah contoh lain yang menggunakan nilai string, bukan peta.
sumber
Dalam konteks enum, menggunakan
@JsonValue
sekarang (sejak 2.0) berfungsi untuk serialisasi dan deserialisasi.Menurut javadoc jackson-annotations untuk
@JsonValue
:Jadi memiliki
Event
enum yang dianotasi sama seperti karya di atas (untuk serialisasi dan deserialisasi) dengan jackson 2.0+.sumber
Selain menggunakan @JsonSerialize @JsonDeserialize, Anda juga dapat menggunakan SerializationFeature dan DeserializationFeature (pengikat jackson) di mapper objek.
Seperti DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, yang memberikan tipe enum default jika yang disediakan tidak didefinisikan dalam kelas enum.
sumber
Cara paling sederhana yang saya temukan adalah menggunakan anotasi @ JsonFormat.Shape.OBJECT untuk enum.
sumber
Dalam kasus saya, inilah yang diselesaikan:
Serialize dan deserializes json berikut:
Saya harap ini membantu!
sumber