Saya mendapatkan error berikut ketika mencoba untuk mendapatkan JSON permintaan dan proses ini:
org.codehaus.jackson.peta.JsonMappingException: Tidak cocok konstruktor ditemukan untuk type [tipe sederhana, kelas com.myweb.ApplesDO]: tidak dapat instantiate dari JSON object (perlu menambahkan/mengaktifkan jenis informasi?)
Berikut ini adalah JSON saya mencoba untuk mengirim:
{
"applesDO" : [
{
"apple" : "Green Apple"
},
{
"apple" : "Red Apple"
}
]
}
Di Controller, saya memiliki metode berikut tanda tangan:
@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
// Method Code
}
AllApplesDO adalah pembungkus dari ApplesDO :
public class AllApplesDO {
private List<ApplesDO> applesDO;
public List<ApplesDO> getApplesDO() {
return applesDO;
}
public void setApplesDO(List<ApplesDO> applesDO) {
this.applesDO = applesDO;
}
}
ApplesDO:
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 adalah mampu mengkonversi JSON ke Jawa objek untuk subclass. Tolong bantu dengan parameter konfigurasi untuk Jackson convert JSON ke Jawa Objek. Saya menggunakan Spring Framework.
EDIT: Termasuk bug utama yang menyebabkan masalah ini pada contoh di atas kelas - Silahkan lihat jawaban yang diterima untuk solusi.
Jadi, akhirnya saya menyadari apa masalahnya. Hal ini tidak Jackson masalah konfigurasi seperti yang saya meragukan.
Sebenarnya masalah itu di ApplesDO Kelas:
public class ApplesDO {
private String apple;
public String getApple() {
return apple;
}
public void setApple(String apple) {
this.apple = apple;
}
public ApplesDO(CustomType custom) {
//constructor Code
}
}
Ada kebiasaan konstruktor yang ditetapkan untuk kelas menjadikannya default constructor. Memperkenalkan boneka pembangun telah membuat kesalahan untuk pergi:
public class ApplesDO {
private String apple;
public String getApple() {
return apple;
}
public void setApple(String apple) {
this.apple = apple;
}
public ApplesDO(CustomType custom) {
//constructor Code
}
//Introducing the dummy constructor
public ApplesDO() {
}
}
Hal ini terjadi karena alasan-alasan ini:
private static class Kondisi { //jackson tertentu }
private static class Kondisi { private Long id;
semua Kondisi() { }
// Setter dan Getter }
Saya ingin menambahkan solusi lain untuk ini yang tidak memerlukan dummy konstruktor. Sejak dummy konstruktor yang sedikit berantakan dan kemudian membingungkan. Kami dapat memberikan yang aman konstruktor dan annotating konstruktor argumen kami memungkinkan jackson untuk menentukan pemetaan antara konstruktor parameter dan field.
jadi berikut ini juga akan bekerja. Perhatikan string di dalam penjelasan harus sesuai dengan nama field.
import com.fasterxml.jackson.annotation.JsonProperty;
public class ApplesDO {
private String apple;
public String getApple() {
return apple;
}
public void setApple(String apple) {
this.apple = apple;
}
public ApplesDO(CustomType custom){
//constructor Code
}
public ApplesDO(@JsonProperty("apple")String apple) {
}
}
Ketika aku berlari ke dalam masalah ini, itu adalah hasil dari mencoba untuk menggunakan inner class untuk melayani sebagai DO. Konstruksi dalam kelas (diam-diam) diperlukan sebuah instance dari kelas yang melingkupi -- yang tidak't tersedia untuk Jackson.
Dalam hal ini, bergerak dalam kelas sendiri .file java tetap masalah.
Umumnya kesalahan ini muncul karena kita tidak membuat konstruktor default tapi dalam kasus saya, masalah itu datang hanya karena aku telah dibuat digunakan kelas objek di dalam kelas induk. Ini telah menyia-nyiakan saya sepanjang hari.
Jempol Aturan: Tambahkan konstruktor default untuk masing-masing kelas anda digunakan sebagai pemetaan kelas. Anda melewatkan ini dan masalah yang timbul!
Hanya menambahkan default constructor dan harus bekerja.
Bisa tolong uji struktur ini. Jika aku ingat benar anda dapat menggunakan cara ini:
{
"applesRequest": {
"applesDO": [
{
"apple": "Green Apple"
},
{
"apple": "Red Apple"
}
]
}
}
Kedua, silakan tambahkan konstruktor default untuk masing-masing kelas ini juga mungkin bisa membantu.
Jika anda mulai annotating constructor, anda harus memberikan keterangan semua bidang.
Pemberitahuan, Staf saya.nama bidang yang dipetakan ke "ANOTHER_NAME" dalam JSON string.
String jsonInString="{\"ANOTHER_NAME\":\"John\",\"age\":\"17\"}";
ObjectMapper mapper = new ObjectMapper();
Staff obj = mapper.readValue(jsonInString, Staff.class);
// print to screen
public static class Staff {
public String name;
public Integer age;
public Staff() {
}
//@JsonCreator - don't need this
public Staff(@JsonProperty("ANOTHER_NAME") String n,@JsonProperty("age") Integer a) {
name=n;age=a;
}
}
Anda harus menyadari apa pilihan Jackson telah tersedia untuk deserialization. Di Jawa, metode argumen nama-nama yang tidak hadir dalam menyusun kode. Yang's mengapa Jackson bisa't umumnya menggunakan konstruktor untuk membuat sebuah objek didefinisikan dengan segala sesuatu yang sudah ditetapkan.
Jadi, jika ada yang kosong konstruktor dan ada juga setter, menggunakan konstruktor kosong dan setter. Jika tidak ada setter, beberapa sihir gelap (refleksi) digunakan untuk melakukan hal itu.
Jika anda ingin menggunakan konstruktor dengan Jackson, anda harus menggunakan anotasi, seperti yang disebutkan oleh @PiersyP dalam jawabannya. Anda juga dapat menggunakan builder pola. Jika anda mengalami beberapa pengecualian, good luck. Penanganan kesalahan di Jackson benar-benar menyebalkan, it's sulit untuk memahami bahwa omong kosong dalam pesan kesalahan.
Mengenai publikasi terakhir saya punya masalah yang sama di mana menggunakan Lombok 1.18.* dihasilkan masalah.
Solusi saya adalah untuk menambahkan @NoArgsConstructor (konstruktor tanpa parameter), sejak @Data mencakup secara default @RequiredArgsConstructor (Konstruktor dengan parameter).
lombok Dokumentasi https://projectlombok.org/features/all
Yang akan memecahkan masalah:
package example.counter;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
@NoArgsConstructor
public class CounterRequest {
@NotNull
private final Integer int1;
@NotNull
private final Integer int2;
}
Bagi saya, ini digunakan untuk bekerja, tapi upgrade perpustakaan yang disebabkan masalah ini muncul. Masalah itu memiliki kelas seperti ini:
package example.counter;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
public class CounterRequest {
@NotNull
private final Integer int1;
@NotNull
private final Integer int2;
}
Menggunakan lombok:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
</dependency>
Jatuh kembali ke
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
Tetap masalah. Tidak yakin mengapa, tapi ingin dokumen itu untuk masa depan.