Beim Versuch, eine JSON-Anforderung abzurufen und zu verarbeiten, wird folgende Fehlermeldung angezeigt:
org.codehaus.jackson.map.JsonMappingException: Kein geeigneter Konstruktor für Typ [einfacher Typ, Klasse com.myweb.ApplesDO] gefunden: Kann nicht vom JSON-Objekt instanziieren (müssen Typinformationen hinzugefügt / aktiviert werden?)
Hier ist der JSON, den ich senden möchte:
{
"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, um eine Lösung zu finden.
Antworten:
Endlich wurde mir klar, wo das Problem liegt. Es ist kein Jackson-Konfigurationsproblem, wie ich bezweifelte.
Eigentlich war das Problem in der ApplesDO- Klasse:
Für die Klasse wurde ein benutzerdefinierter Konstruktor definiert, der sie zum Standardkonstruktor macht. Die Einführung eines Dummy-Konstruktors hat den Fehler behoben:
quelle
Dies geschieht aus folgenden Gründen:
Ihre innere Klasse sollte als statisch definiert sein
Möglicherweise haben Sie keinen Standardkonstruktor in Ihrer Klasse ( UPDATE: Dies scheint nicht der Fall zu sein).
Es kann sein, dass Ihre Setter nicht richtig definiert oder nicht sichtbar sind (z. B. privater Setter).
quelle
Ich möchte eine weitere Lösung hinzufügen, für die kein Dummy-Konstruktor erforderlich ist. Da sind Dummy-Konstruktoren etwas chaotisch und anschließend verwirrend. Wir können einen sicheren Konstruktor bereitstellen und durch Annotieren der Konstruktorargumente erlauben wir Jackson, die Zuordnung zwischen Konstruktorparameter und Feld zu bestimmen.
Das Folgende wird also auch funktionieren. Beachten Sie, dass die Zeichenfolge in der Anmerkung mit dem Feldnamen übereinstimmen muss.
quelle
@JsonCreator
der Konstruktor auch mit hinzugefügt werden@JsonProperty
.Als ich auf dieses Problem stieß, war es das Ergebnis des Versuchs, eine innere Klasse als DO zu verwenden. Der Aufbau der inneren Klasse (stillschweigend) erforderte eine Instanz der einschließenden Klasse - die Jackson nicht zur Verfügung stand.
In diesem Fall wurde das Problem behoben, indem die innere Klasse in eine eigene Java-Datei verschoben wurde.
quelle
Im Allgemeinen tritt dieser Fehler auf, weil wir keinen Standardkonstruktor erstellen, aber in meinem Fall trat das Problem nur auf, weil ich eine verwendete Objektklasse innerhalb der übergeordneten Klasse erstellt habe. Das hat meinen ganzen Tag verschwendet.
quelle
static
.Daumenregel : Fügen Sie für jede Klasse, die Sie als Zuordnungsklasse verwendet haben, einen Standardkonstruktor hinzu. Sie haben dies verpasst und es tritt ein Problem auf!
Fügen Sie einfach den Standardkonstruktor hinzu und es sollte funktionieren.
quelle
Können Sie bitte diese Struktur testen? Wenn ich mich richtig erinnere, können Sie es folgendermaßen verwenden:
Zweitens fügen Sie jeder Klasse einen Standardkonstruktor hinzu, der ebenfalls hilfreich sein könnte.
quelle
Sie müssen einen leeren Dummy-Konstruktor in unserer Modellklasse erstellen. Während Sie json zuordnen, wird er durch die Setter-Methode festgelegt.
quelle
Wenn Sie mit dem Annotieren des Konstruktors beginnen, müssen Sie alle Felder mit Annotationen versehen.
Beachten Sie, dass mein Feld Staff.name in der JSON-Zeichenfolge "ANOTHER_NAME" zugeordnet ist.
quelle
Sie müssen erkennen, welche Optionen Jackson für die Deserialisierung zur Verfügung hat. In Java sind Methodenargumentnamen im kompilierten Code nicht vorhanden. Aus diesem Grund kann Jackson im Allgemeinen keine Konstruktoren verwenden, um ein genau definiertes Objekt zu erstellen, bei dem bereits alles festgelegt ist.
Wenn es also einen leeren Konstruktor gibt und es auch Setter gibt, werden der leere Konstruktor und die Setter verwendet. Wenn es keine Setter gibt, wird etwas dunkle Magie (Reflexionen) verwendet, um dies zu tun.
Wenn Sie einen Konstruktor mit Jackson verwenden möchten, müssen Sie die Anmerkungen verwenden, die von @PiersyP in seiner Antwort erwähnt wurden. Sie können auch ein Builder-Muster verwenden. Wenn Sie auf einige Ausnahmen stoßen, viel Glück. Fehlerbehandlung in Jackson ist zum Kotzen, es ist schwer zu verstehen, dass Kauderwelsch in Fehlermeldungen.
quelle
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-Dokumentation https://projectlombok.org/features/all
Das würde das Problem lösen:
quelle
Fehlerhafte benutzerdefinierte Jackson-Serializer / Deserializer könnten ebenfalls das Problem sein. Obwohl es nicht Ihr Fall ist, ist es erwähnenswert.
Ich hatte die gleiche Ausnahme und das war der Fall.
quelle
Früher funktionierte dies, aber durch das Aktualisieren von Bibliotheken trat dieses Problem auf. Das Problem war, eine Klasse wie diese zu haben:
Mit Lombok:
Zurückfallen auf
Das Problem wurde behoben. Ich weiß nicht warum, wollte es aber für die Zukunft dokumentieren.
quelle