Jersey: No suitable constructor found for type [simple type, class Thing]: can not instantiate from JSON object

Eduardo picture Eduardo · Jun 28, 2015 · Viewed 47.1k times · Source

I have a resource with a method like:

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

Thing:

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

When I make a PUT request like:

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

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

I get the following response:

No suitable constructor found for type [simple type, class Thing]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)

Why is Jersey/Jackson not deserializing my JSON object into my POJO?

Answer

Paul Samsotha picture Paul Samsotha · Jun 28, 2015

You need a no-arg constructor and setters, or use @JsonCreator. Easiest thing to do would be just to add the no-arg with setters. Jackson needs the setters when deserializing. For serialization, all that's needed are getters.

EDIT

To keep it immutable, you can use @JsonCreator on the constructor. For example

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

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

See more Jackson Annotations: @JsonCreator demystified