Saya mendapatkan kesalahan berikut ketika mencoba untuk mendapatkan permintaan JSON dan memprosesnya:
org.codehaus.jackson.map.JsonMappingException: Tidak ditemukan konstruktor yang cocok untuk tipe [tipe sederhana, kelas com.myweb.ApplesDO]: tidak dapat instantiate dari objek JSON (perlu menambah / mengaktifkan informasi jenis?)
Inilah JSON yang saya coba kirim:
{
"applesDO" : [
{
"apple" : "Green Apple"
},
{
"apple" : "Red Apple"
}
]
}
Di Kontroler, saya memiliki tanda tangan metode berikut:
@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
// Method Code
}
AllApplesDO adalah pembungkus ApplesDO:
public class AllApplesDO {
private List<ApplesDO> applesDO;
public List<ApplesDO> getApplesDO() {
return applesDO;
}
public void setApplesDO(List<ApplesDO> applesDO) {
this.applesDO = applesDO;
}
}
ApelDO:
public class ApplesDO {
private String apple;
public String getApple() {
return apple;
}
public void setApple(String appl) {
this.apple = apple;
}
public ApplesDO(CustomType custom){
//constructor Code
}
}
Saya berpikir bahwa Jackson tidak dapat mengubah JSON menjadi objek Java untuk subkelas. Tolong bantu dengan parameter konfigurasi untuk Jackson untuk mengkonversi JSON menjadi Java Objects. Saya menggunakan Spring Framework.
EDIT: Termasuk bug utama yang menyebabkan masalah ini di kelas sampel di atas - Silakan lihat jawaban yang diterima untuk solusi.
Jawaban:
Jadi, akhirnya saya menyadari apa masalahnya. Ini bukan masalah konfigurasi Jackson karena saya ragu.
Sebenarnya masalahnya ada di ApplesDO Class:
Ada konstruktor khusus yang ditentukan untuk kelas menjadikannya konstruktor default. Memperkenalkan konstruktor dummy telah membuat kesalahan hilang:
sumber
Ini terjadi karena alasan berikut:
kelas batin Anda harus didefinisikan sebagai statis
Mungkin Anda tidak mendapat konstruktor default di kelas Anda ( PEMBARUAN: Tampaknya tidak demikian)
Bisa jadi setter Anda tidak didefinisikan dengan benar atau tidak terlihat (mis. Setter pribadi)
sumber
Saya ingin menambahkan solusi lain untuk ini yang tidak memerlukan konstruktor dummy. Karena dummy constructor agak berantakan dan selanjutnya membingungkan. Kami dapat menyediakan konstruktor yang aman dan dengan menganotasi argumen konstruktor, kami mengizinkan jackson untuk menentukan pemetaan antara parameter konstruktor dan bidang.
jadi berikut ini juga akan berfungsi. Perhatikan string di dalam anotasi harus cocok dengan nama bidang.
sumber
@JsonCreator
konstruktor dengan@JsonProperty
.Ketika saya mengalami masalah ini, itu adalah hasil dari mencoba menggunakan kelas batin untuk berfungsi sebagai DO. Konstruksi kelas dalam (diam-diam) membutuhkan turunan dari kelas penutup - yang tidak tersedia untuk Jackson.
Dalam hal ini, memindahkan kelas dalam ke file .java sendiri memperbaiki masalah.
sumber
Secara umum kesalahan ini terjadi karena kita tidak membuat konstruktor default tetapi dalam kasus saya Masalahnya datang hanya karena saya telah membuat kelas objek yang digunakan di dalam kelas induk. Ini telah menghabiskan seluruh hari saya.
sumber
static
.Aturan Jempol : Tambahkan konstruktor default untuk setiap kelas yang Anda gunakan sebagai kelas pemetaan. Anda melewatkan ini dan masalah muncul!
Cukup tambahkan konstruktor default dan itu akan berfungsi.
sumber
Bisakah Anda menguji struktur ini. Jika saya ingat benar Anda dapat menggunakannya dengan cara ini:
Kedua, tolong tambahkan konstruktor default untuk setiap kelas yang mungkin juga membantu.
sumber
Anda harus membuat konstruktor kosong dummy di kelas model kami. Jadi saat memetakan json, itu ditetapkan dengan metode setter.
sumber
Jika Anda memulai anotasi konstruktor, Anda harus memberi anotasi pada semua bidang.
Perhatikan, bidang Staff.name saya dipetakan ke "ANOTHER_NAME" dalam string JSON.
sumber
Anda harus menyadari opsi apa yang tersedia untuk deserialisasi. Di Jawa, nama argumen metode tidak ada dalam kode yang dikompilasi. Itulah sebabnya Jackson umumnya tidak dapat menggunakan konstruktor untuk membuat objek yang terdefinisi dengan baik dengan semua yang telah ditetapkan.
Jadi, jika ada konstruktor kosong dan ada juga setter, itu menggunakan konstruktor kosong dan setter. Jika tidak ada setter, beberapa sihir gelap (refleksi) digunakan untuk melakukannya.
Jika Anda ingin menggunakan konstruktor dengan Jackson, Anda harus menggunakan anotasi seperti yang disebutkan oleh @PiersyP dalam jawabannya. Anda juga dapat menggunakan pola pembangun. Jika Anda menemukan beberapa pengecualian, semoga berhasil. Menangani kesalahan di Jackson sangat menyebalkan, sulit untuk memahami bahwa omong kosong dalam pesan kesalahan.
sumber
Mengenai publikasi terakhir saya punya masalah yang sama di mana menggunakan Lombok 1.18. * Menghasilkan masalah.
Solusi saya adalah menambahkan @NoArgsConstructor (konstruktor tanpa parameter), karena @ Data menyertakan secara default @RequiredArgsConstructor (Konstruktor dengan parameter).
Dokumentasi lombok https://projectlombok.org/features/all
Itu akan memecahkan masalah:
sumber
Gagal kustom jackson Serializers / Deserializers juga bisa menjadi masalah. Meskipun ini bukan kasus Anda, perlu disebutkan.
Saya menghadapi pengecualian yang sama dan itulah yang terjadi.
sumber
Bagi saya, ini dulu berfungsi, tetapi memutakhirkan perpustakaan menyebabkan masalah ini muncul. Masalahnya memiliki kelas seperti ini:
Menggunakan lombok:
Jatuh kembali ke
Memperbaiki masalah. Tidak yakin mengapa, tetapi ingin mendokumentasikannya untuk masa depan.
sumber