Saya memiliki format Tanggal yang berasal dari API seperti ini:
"start_time": "2015-10-1 3:00 PM GMT+1:00"
Yaitu YYYY-DD-MM HH: MM am / pm GMT timestamp. Saya memetakan nilai ini ke variabel Tanggal di POJO. Jelas, ini menunjukkan kesalahan konversi.
Saya ingin tahu 2 hal:
- Apa format yang perlu saya gunakan untuk melakukan konversi dengan Jackson? Apakah Date jenis bidang yang baik untuk ini?
- Secara umum, apakah ada cara untuk memproses variabel sebelum dipetakan ke anggota Object oleh Jackson? Sesuatu seperti, mengubah format, perhitungan, dll.
Date
kelas. java.time, API tanggal dan waktu Jawa modern, telah menggantinya hampir 5 tahun yang lalu. Gunakan dan FasterXML / jackson-modules-java8 .Jawaban:
Date
adalah tipe bidang halus untuk ini. Anda dapat membuat JSON parse-mampu dengan cukup mudah dengan menggunakanObjectMapper.setDateFormat
:Iya. Anda memiliki beberapa opsi, termasuk menerapkan kebiasaan
JsonDeserializer
, misalnya memperluasJsonDeserializer<Date>
. Ini awal yang bagus.sumber
LocalDateTime
atauZonedDateTime
bukanDate
? KarenaDate
pada dasarnya sudah usang (atau setidaknya banyak metodenya), saya ingin menggunakan alternatif itu.java.util.Date
secara eksplisit saya ingin menunjukkan bahwa ini tidak berfungsi untukjava.sql.Date.
Lihat juga jawaban saya di bawah ini.Sejak Jackson v2.0, Anda dapat menggunakan anotasi @JsonFormat secara langsung pada anggota Object;
sumber
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
Tentu saja ada cara otomatis yang disebut serialisasi dan deserialisasi dan Anda dapat mendefinisikannya dengan anotasi tertentu ( @JsonSerialize , @JsonDeserialize ) seperti yang disebutkan oleh pb2q juga.
Anda dapat menggunakan java.util.Date dan java.util.Calendar ... dan mungkin JodaTime juga.
Penjelasan @JsonFormat tidak berfungsi untuk saya seperti yang saya inginkan (telah menyesuaikan zona waktu dengan nilai yang berbeda) selama deserialisasi (serialisasi bekerja dengan sempurna):
Anda perlu menggunakan serializer khusus dan deserializer khusus alih-alih anotasi @JsonFormat jika Anda ingin hasil yang diprediksi. Saya telah menemukan tutorial dan solusi yang sangat bagus di sini http://www.baeldung.com/jackson-serialize-dates
Ada contoh untuk bidang Tanggal tetapi saya perlu untuk bidang Kalender jadi di sini adalah implementasi saya :
Kelas serializer :
Kelas deserializer :
dan penggunaan kelas-kelas di atas:
Dengan menggunakan implementasi ini, pelaksanaan proses serialisasi dan deserialisasi secara berurutan menghasilkan nilai asal.
Hanya menggunakan anotasi @JsonFormat deserialization memberikan hasil yang berbeda saya pikir karena pengaturan default zona waktu internal perpustakaan apa yang tidak dapat Anda ubah dengan parameter anotasi (itu adalah pengalaman saya dengan Jackson library 2.5.3 dan 2.6.3 versi juga).
sumber
Hanya contoh lengkap untuk aplikasi boot musim semi dengan
RFC3339
format datetimesumber
Untuk menambahkan karakter seperti T dan Z di teman kencan Anda
keluaran
sumber
Bekerja untukku. SpringBoot.
keluaran:
sumber
Membangun di atas @ miklov-kriven jawaban yang sangat membantu, saya harap dua hal tambahan ini bermanfaat bagi seseorang:
(1) Saya menemukan ide bagus untuk memasukkan serializer dan de-serializer sebagai kelas statis dalam kelas yang sama. NB, menggunakan ThreadLocal untuk keamanan thread dari SimpleDateFormat.
(2) Sebagai alternatif untuk menggunakan @JsonSerialize dan @JsonDeserialize anotasi pada setiap anggota kelas, Anda juga dapat mempertimbangkan mengganti serialisasi default Jackson dengan menerapkan serialisasi khusus pada tingkat aplikasi, yaitu semua anggota kelas tipe Date akan diserialisasi oleh Jackson menggunakan serialisasi khusus ini tanpa anotasi eksplisit di setiap bidang. Jika Anda menggunakan Spring Boot misalnya, salah satu cara untuk melakukannya adalah sebagai berikut:
sumber
Jika ada yang punya masalah dengan menggunakan format tanggal kustom untuk java.sql.Date, ini adalah solusi paling sederhana:
(SO-jawaban ini menyelamatkan saya dari banyak masalah: https://stackoverflow.com/a/35212795/3149048 )
Jackson menggunakan SqlDateSerializer secara default untuk java.sql.Date, tetapi saat ini, serializer ini tidak mempertimbangkan format tanggal, lihat masalah ini: https://github.com/FasterXML/jackson-databind/issues/1407 . Solusinya adalah dengan mendaftarkan serializer yang berbeda untuk java.sql.Date seperti yang ditunjukkan pada contoh kode.
sumber
Saya ingin menunjukkan bahwa pengaturan
SimpleDateFormat
sejenis yang dijelaskan dalam jawaban lain hanya berfungsi untukjava.util.Date
yang saya anggap dimaksud dalam pertanyaan. Tetapi untukjava.sql.Date
formatter tidak berfungsi. Dalam kasus saya, tidak terlalu jelas mengapa formatter tidak bekerja karena dalam model yang harus diserialisasi lapangan sebenarnya adalahjava.utl.Date
tetapi objek yang sebenarnya berakhir dengan ajava.sql.Date
. Ini dimungkinkan karenaJadi ini sebenarnya valid
Jadi jika Anda bertanya-tanya mengapa bidang Tanggal Anda tidak diformat dengan benar, pastikan objek tersebut benar-benar a
java.util.Date
.Di sini juga disebutkan mengapa penanganan
java.sql.Date
tidak akan ditambahkan.sumber
Date
kelas yang berbeda ini . Namun, akhir-akhir ini tidak ada yang seharusnyaSimpleDateFormat
. java.time, API tanggal dan waktu Java modern, telah menggantinya hampir 5 tahun yang lalu. Gunakan dan FasterXML / jackson-modules-java8 .