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?
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
I'm not absolutely positive, but I think this is it.
The way that Jackson wants to work is this: it creates the object using the default (no argument) constructor. Then it uses setters to set each of the instance variables. This may seem like the long way around, but it's really the only way, because Jackson can't really be smart enough to figure out what order to pass the constructor parameters in. So your code has two main issues (well, three, but I'm going to assume that your class was called Stock before you mostly cleaned it up for posting ;-) ).
1. You need a no-argument constructor. From what I know, java provides a default constructor if you don't write one, but as soon as you make any constructor, the default no-argument constructor goes away.
2. You need setters for your instance variables (and making them public isn't good enough, they have to have actual setters). Oh it looks like your instance variables are final, that's not going to work. My favorite way to manage all the copy/pasted setters is to use a library called lombok. Anyway, for now you just need those setters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With