Jersey: aucun constructeur trouvé adapté au type [type simple, chose de classe]: ne peut pas instancier à partir de l'objet JSON

j'ai une ressource avec une méthode comme:

@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();
    }
}

Chose:

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

Quand je fais une requête du type:

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

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

j'obtiens la réponse suivante:

aucun constructeur adapté trouvé pour le type [type simple, chose de classe]: can pas d'instantiate de l'objet JSON (manque de constructeur par défaut ou créateur, ou peut-être besoin d'ajouter/activer le type d'informations?)

pourquoi Jersey / Jackson ne désérialise pas mon Un objet JSON dans mon POJO?

25
demandé sur Edd 2015-06-28 01:55:43

2 réponses

vous avez besoin d'un constructeur no-arg et de setters, ou utilisez @JsonCreator. La chose la plus facile à faire serait d'ajouter le no-arg avec setters. Jackson a besoin des setters quand il désérialise. Pour la sérialisation, tout ce qui est nécessaire sont getters.

EDIT

Pour garder immuable, vous pouvez utiliser @JsonCreator dans le constructeur. Par exemple,

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

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

Voir plus Jackson Annotations: @JsonCreator demystified

34
répondu Paul Samsotha 2015-06-27 23:20:42

Je ne suis pas absolument certain, mais je pense que c'est tout.

Le chemin que Jackson veut travailler, c'est ceci: il crée l'objet à l'aide de la valeur par défaut (sans argument) constructeur. Ensuite, il utilise setters pour définir chacune des variables d'instance. Cela peut sembler long, mais c'est vraiment la seule façon, parce que Jackson peut pas vraiment être assez intelligent pour comprendre ce que pour passer les paramètres du constructeur. Donc votre code a deux problèmes principaux (bien, trois, mais je vais supposons que votre classe s'appelle Stock avant que vous ne la nettoyiez pour l'afficher ;-) ).

1. Vous avez besoin d'un constructeur sans argument. De ce que je sais, java fournit un constructeur par défaut si vous n'en écrivez pas un, mais dès que vous créez un constructeur, le constructeur par défaut sans argument disparaît.

2. Vous avez besoin de setters pour vos variables d'instance (et les rendre publiques n'est pas suffisant, ils doivent avoir des setters réels). Oh ça ressemble à tes variables d'instance sont définitives, qui ne va pas au travail. Ma façon préférée de gérer tous les copier/coller poseurs est d'utiliser une bibliothèque appelée lombok. Bref, pour l'instant, tu as juste besoin de ces setters.

3
répondu OrigamiMarie 2015-06-27 23:10:52