it-swarm.com.de

Jersey: Es wurde kein geeigneter Konstruktor für den Typ [einfacher Typ, Klasse Thing] gefunden: Kann nicht vom JSON-Objekt instanziieren

Ich habe eine Ressource mit einer Methode wie:

@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/add")
public Response putThing(Thing thing) {
    try {
        //Do something with Thing object
        return Response.status(HttpStatus.SC_OK).build();
    } catch (Exception e) {
        log.error("Request failed", e);
        return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
    }
}

Sache:

public class Thing {
    private final String symbol;
    private final String name;

    public Stock(String symbol, String name) {
        this.symbol = symbol;
        this.name = name;
    }

    public String getSymbol() {
        return this.symbol;
    }

    public String getName() {
        return this.name;
    }
}

Wenn ich eine PUT-Anfrage mache wie:

PUT /rest/add HTTP/1.1
Host: localhost:8135
Content-Type: application/json
Cache-Control: no-cache

{"symbol":"some symbol","name":"some name"}

Ich erhalte folgende Antwort:

Kein passender Konstruktor für Typ [einfacher Typ, Klasse Thing] gefunden: Kann nicht aus JSON-Objekt instanziieren (fehlender Standardkonstruktor oder -ersteller oder möglicherweise müssen Typinformationen hinzugefügt/aktiviert werden?)

Warum deserialisiert Jersey/Jackson mein JSON-Objekt nicht in meinem POJO?

25
Edd

Sie benötigen einen Konstruktor und Setter ohne Argumente oder verwenden @JsonCreator. Am einfachsten wäre es, nur das No-Arg mit Setter hinzuzufügen. Jackson braucht die Setter beim Deserialisieren. Für die Serialisierung werden lediglich Getter benötigt.

[~ # ~] edit [~ # ~]

Um es unveränderlich zu halten, können Sie @JsonCreator auf dem Konstruktor. Beispielsweise

@JsonCreator
public Thing(@JsonProperty("symbol") String symbol, 
             @JsonProperty("name") String name) {

    this.symbol = symbol;
    this.name = name;
}

Weitere Jackson Annotations: @JsonCreator entmystifiziert

37
Paul Samsotha

Ich bin nicht absolut positiv, aber ich denke, das ist es.

Jackson möchte folgendermaßen arbeiten: Es erstellt das Objekt mit dem Standardkonstruktor (ohne Argument). Anschließend werden Setter verwendet, um die einzelnen Instanzvariablen festzulegen. Dies mag weit herum scheinen, aber es ist wirklich der einzige Weg, da Jackson nicht klug genug sein kann, um herauszufinden, in welcher Reihenfolge die Konstruktorparameter übergeben werden sollen. Ihr Code hat also zwei Hauptprobleme (drei, aber ...) Ich gehe davon aus, dass deine Klasse "Stock" hieß, bevor du sie zum Posten größtenteils bereinigt hast ;-)).
1. Sie benötigen einen Konstruktor ohne Argumente. Soweit ich weiß, stellt Java einen Standardkonstruktor bereit, wenn Sie keinen schreiben, aber sobald Sie einen Konstruktor erstellen, wird der Standardkonstruktor ohne Argumente nicht mehr angezeigt.
2. Sie benötigen Setter für Ihre Instanzvariablen (und ihre Veröffentlichung ist nicht gut genug, sie müssen über tatsächliche Setter verfügen). Ihre Instanzvariablen scheinen endgültig zu sein, das wird nicht funktionieren. Meine Lieblingsmethode zum Verwalten aller kopierten/eingefügten Setter ist die Verwendung einer Bibliothek namens lombok. Wie auch immer, fürs Erste brauchst du nur diese Setter.

3
OrigamiMarie