it-swarm.com.de

JsonMappingException: Es wurde kein passender Konstruktor gefunden

Beim Versuch, eine JSON-Anforderung abzurufen und zu verarbeiten, wird die folgende Fehlermeldung angezeigt:

org.codehaus.jackson.map.JsonMappingException: Kein geeigneter Konstruktor für Typ [einfacher Typ, Klasse com.myweb.ApplesDO] gefunden: Kann nicht aus JSON-Objekten instanziieren (müssen Typinformationen hinzufügen/aktivieren?)

Hier ist der JSON, den ich zu senden versuche:

{
  "applesDO" : [
    {
      "Apple" : "Green Apple"
    },
    {
      "Apple" : "Red Apple"
    }
  ]
}

In Controller habe ich die folgende Methodensignatur:

@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
    // Method Code
}

AllApplesDO ist ein Wrapper von 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
    }
}

Ich denke, dass Jackson JSON nicht in Java-Objekte für Unterklassen konvertieren kann. Bitte helfen Sie mit den Konfigurationsparametern für Jackson, um JSON in Java-Objekte zu konvertieren. Ich benutze Spring Framework.

BEARBEITEN: Der Hauptfehler, der dieses Problem verursacht, wurde in die obige Beispielklasse aufgenommen. Bitte suchen Sie nach einer akzeptierten Antwort.

384
Lucky Murari

So wurde mir endlich klar, was das Problem ist. Es ist kein Jackson-Konfigurationsproblem, wie ich bezweifelte.

Eigentlich war das Problem in ApplesDO Class:

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
    }
}

Für die Klasse wurde ein benutzerdefinierter Konstruktor definiert, der ihn zum Standardkonstruktor macht. Die Einführung eines Dummy-Konstruktors hat den Fehler gemacht, zu verschwinden:

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() {
    }

}
518
Lucky Murari

Dies geschieht aus folgenden Gründen:

  1. ihre innere Klasse sollte als static definiert sein.

    private static class Condition {  //jackson specific    
    }
    
  2. Möglicherweise haben Sie in Ihrer Klasse keinen Standardkonstruktor ( UPDATE: Dies scheint nicht der Fall zu sein).

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters and Getters
    }
    
  3. Möglicherweise sind Ihre Setter nicht richtig definiert oder nicht sichtbar (z. B. private Setter)

349
azerafati

Ich möchte eine weitere Lösung hinzufügen, für die kein Dummy-Konstruktor erforderlich ist. Da Dummy-Konstruktoren ein bisschen chaotisch und anschließend verwirrend sind. Wir können einen sicheren Konstruktor bereitstellen. Indem wir die Konstruktorargumente kommentieren, können wir die Zuordnung zwischen Konstruktorparameter und Feld bestimmen.

das Folgende wird auch funktionieren. Beachten Sie, dass die Zeichenfolge in der Anmerkung mit dem Feldnamen übereinstimmen muss.

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) {
        }

}
56
PiersyP

Als ich auf dieses Problem stieß, war es das Ergebnis eines Versuchs, eine innere Klasse als DO zu verwenden. Der Bau der inneren Klasse (lautlos) erforderte eine Instanz der umgebenden Klasse - die Jackson nicht zur Verfügung stand.

In diesem Fall wurde das Problem durch Verschieben der inneren Klasse in eine eigene .Java-Datei behoben.

28
jmarks

Im Allgemeinen tritt dieser Fehler auf, weil wir keinen Standardkonstruktor erstellen, aber in meinem Fall. Das hat meinen ganzen Tag verschwendet.

11
alok

Thumb Rule : Fügt einen Standardkonstruktor für jede Klasse hinzu, die Sie als Zuordnungsklasse verwendet haben. Sie haben dies verpasst und es entstehen Probleme!
Fügen Sie einfach den Standardkonstruktor hinzu und es sollte funktionieren.

11
Badal

Können Sie bitte diese Struktur testen? Wenn ich mich recht erinnere, können Sie es folgendermaßen verwenden:

{
    "applesRequest": {
        "applesDO": [
            {
                "Apple": "Green Apple"
            },
            {
                "Apple": "Red Apple"
            }
        ]
    }
}

Zweitens fügen Sie bitte zu jeder Klasse einen Standardkonstruktor hinzu, der möglicherweise ebenfalls hilfreich ist.

10
danny.lesnik

Sie müssen einen leeren Dummy-Konstruktor in unserer Modellklasse erstellen. Wenn Sie also json abbilden, wird dies durch die Setter-Methode festgelegt.

5
Suresh Patil

Wenn Sie mit dem Kommentieren des Konstruktors beginnen, müssen Sie alle Felder mit Anmerkungen versehen.

Beachten Sie, dass mein Staff.name-Feld in JSON-Zeichenfolge "ANOTHER_NAME" zugeordnet ist.

     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;
       }        
    }
4
Vortex

Sie müssen wissen, welche Möglichkeiten Jackson zur Deserialisierung zur Verfügung hat. In Java sind Methodenargumentnamen nicht im kompilierten Code vorhanden. Aus diesem Grund kann Jackson Konstruktoren nicht generell verwenden, um ein gut definiertes Objekt zu erstellen, in dem bereits alles festgelegt ist.

Wenn also ein leerer Konstruktor vorhanden ist und es auch Setter gibt, werden der leere Konstruktor und die Setter verwendet. Wenn es keine Setter gibt, wird dazu dunkle Magie (Reflexionen) verwendet.

Wenn Sie einen Konstruktor mit Jackson verwenden möchten, müssen Sie die von @PiersyP in seiner Antwort genannten Anmerkungen verwenden. Sie können auch ein Builder-Muster verwenden. Wenn Sie auf einige Ausnahmen stoßen, viel Glück. Die Fehlerbehandlung in Jackson ist eine Scheiße, es ist schwer zu verstehen, dass in Fehlermeldungen Quatsch gemacht wird.

3
Vlasec

In Bezug auf die letzte Veröffentlichung hatte ich das gleiche Problem, bei dem die Verwendung von Lombok 1.18. * Das Problem verursachte.

Meine Lösung bestand darin, @NoArgsConstructor (Konstruktor ohne Parameter) hinzuzufügen, da @Data standardmäßig @RequiredArgsConstructor (Konstruktor mit Parametern) enthält.

lombok Documentation https://projectlombok.org/features/all

Das würde das Problem lösen:

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;
}
0
Felipe Ceballos

Das Versagen von benutzerdefinierten Jackson-Serialisierern/Deserialisierern könnte ebenfalls das Problem sein. Obwohl es nicht Ihr Fall ist, ist es erwähnenswert.

Ich sah die gleiche Ausnahme und das war der Fall.

0
Artem Novikov

Für mich funktionierte das früher, aber beim Aktualisieren von Bibliotheken wurde dieses Problem angezeigt. Das Problem war, eine Klasse wie diese zu haben:

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;
}

Lombok verwenden:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
</dependency>

Rückfall auf

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
</dependency>

Problem behoben Nicht sicher warum, wollte es aber für die Zukunft dokumentieren.

0
eis