Primesc următorul mesaj de eroare atunci când încearcă pentru a obține o cerere JSON și procesul acesta:
org.codehaus.jackson.harta.JsonMappingException: Nu potrivit constructorului găsit pentru tip [tip simplu, clasa com.myweb.ApplesDO]: nu se poate instantia la obiect JSON (nevoie pentru a adăuga/activa tip de informații?)
Aici este JSON sunt încercarea de a trimite:
{
"applesDO" : [
{
"apple" : "Green Apple"
},
{
"apple" : "Red Apple"
}
]
}
În Controler, am urmatoarea metoda semnătura:
@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
// Method Code
}
AllApplesDO este un înveliș de 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
}
}
Cred că Jackson este în imposibilitatea de a converti JSON în obiecte Java pentru subclase. Vă rugăm să ajute cu parametrii de configurare pentru Jackson pentru a converti JSON în Obiecte Java. Eu sunt, folosind Cadru de Primăvară.
EDIT: Inclus majore bug care cauzează această problemă în cele de mai sus clasa de proba - vă Rugăm să căutați răspunsul acceptat de soluție.
Deci, în cele din urmă mi-am dat seama care este problema. Acesta nu este un Jackson problemă de configurare ca m-am îndoit.
De fapt problema a fost în ApplesDO Clasa:
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
}
}
Acolo era un obicei constructor definit pentru clasa făcându-l pe constructorul implicit. Introducerea unui manechin constructorul a făcut eroarea de a pleca:
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() {
}
}
Acest lucru se întâmplă pentru aceste motive:
private static clasa Condiție { //jackson specifice }
private static clasa Condiție { privat Timp de identitate;
publice Condiția() { }
// Setteri și Getters }
Aș dori să adaug o altă soluție care nu are nevoie de un manechin constructor. Deoarece dummy constructori sunt un pic murdar și, ulterior, confuz. Putem oferi o siguranță constructor și prin adnotarea constructorul argumente ne permite jackson pentru a determina mapare între constructor parametru și de teren.
așa că următorul va lucra, de asemenea. Notă șir în interiorul adnotarea trebuie să se potrivească cu numele câmpului.
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) {
}
}
Când m-am întâlnit cu această problemă, a fost o urmare a încerca să utilizați o clasă internă pentru a servi ca FACE. Construcția de clasa interior (în tăcere) este necesar un exemplu de închidere clasa-care a fost't disponibile pentru Jackson.
În acest caz, se deplasează clasa interior la propriu .fișier java a rezolvat problema.
Regula: Adăugați un constructor implicit pentru fiecare clasă ai folosit ca o mapare de clasă. Ai ratat acest lucru și emite apar!
Pur și simplu adăugați constructorul implicit și ar trebui să funcționeze.
Puteți să vă rugăm să testați această structură. Dacă îmi amintesc corect, puteți folosi în felul acesta:
{
"applesRequest": {
"applesDO": [
{
"apple": "Green Apple"
},
{
"apple": "Red Apple"
}
]
}
}
Al doilea rând, vă rugăm să adăugați constructorul implicit pentru fiecare clasă este, de asemenea, ar putea ajuta.
Dacă începeți adnotarea constructor, trebuie să adnota toate domeniile de activitate.
Observați, Personalul meu.numele de domeniu este mapat la "ANOTHER_NAME" în 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;
}
}
Trebuie să dai seama ce opțiuni Jackson are la dispoziție pentru deserializarea. În Java, metoda argument numele nu sunt prezente în codul compilat. Ca's de ce Jackson poate't folosesc, în general, constructorii pentru a crea un obiect bine definit cu totul deja stabilit.
Deci, dacă există un gol constructor și există, de asemenea, setteri, se folosește gol constructor și setteri. Dacă nu există setteri, magia neagră (reflecții) este folosit pentru a face.
Dacă doriți să utilizați un constructor cu Jackson, trebuie să utilizați adnotări după cum sa menționat de @PiersyP în răspunsul său. Puteți folosi, de asemenea, un constructor model. Dacă vă confruntați cu unele excepții, noroc. Eroare de manipulare în Jackson sucks big time, l's greu de înțeles că păsărească în mesaje de eroare.
Cu privire la ultima publicare, am avut aceeași problemă în cazul în care utilizarea Lombok 1.18.* generat problema.
Soluția mea a fost să adăugați @NoArgsConstructor (constructor fără parametri), deoarece @de Date include în mod implicit @RequiredArgsConstructor (Constructor cu parametri).
lombok Documentația https://projectlombok.org/features/all
Asta ar putea rezolva problema:
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;
}
Pentru mine, aceasta a lucrat, dar modernizarea bibliotecilor cauzat această problemă să apară. Problema a fost cu o clasa de genul asta:
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;
}
Folosind lombok:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
</dependency>
Care se încadrează înapoi la
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
Sa rezolvat problema. Nu știu de ce, dar a vrut să-document ea pentru viitor.