Reputation: 20384
I'm wondering where to put the @JsonIgnoreProperties(ignoreUnknown = true)
in a Java REST API. I have the following class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.ObjectMapper;
@JsonIgnoreProperties(ignoreUnknown = true)
public class QueuePayload {
private String message;
private String id;
public String getId() {
return this.id;
}
public String getMessage() {
return this.message;
}
public void setId(String id) {
this.id = id;
}
public void setMessage(String message) {
this.message = message;
}
public String serialize() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
}
}
Which I use in a JAX-RS servlet like this:
import javax.jms.JMSException;
import javax.naming.NamingException;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@Path("/v1")
@Produces(MediaType.APPLICATION_JSON)
public class ServiceApiV1 {
@GET
public Response getApiRoot() {
String result = "{\"notice\" : \"It is alive!\"}";
return Response.status(Status.OK).entity(result).build();
}
@POST
@Path("/update")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(UpdatePayload message) {
return Response.status(Status.OK).entity(message).build();
}
}
When I post { "message" : "Test", "id" : "one" }
it works like a charm, but when I post { "message" : "Test", "id" : "one", "sneaked" : "in" }
I get:
SRVE0315E: An exception occurred: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "sneaked"; (Class test.QueuePayload), not marked as ignorable at [Source: com.ibm.ws.webcontainer.srt.SRTInputStream@b7328421; line: 1, column: 7] (through reference chain: test.QueuePayload["sneaked"])
I though @JsonIgnoreProperties(ignoreUnknown = true)
was designed exactly for this use case. I also tried without the property in the servlet and the various permutations. I checked this question and made sure to have imported the same API version in both classes.
What do I miss?
Update
Change the imported classed to codehouse (see above) and ran this test):
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
QueuePayload qp = new QueuePayload();
qp.setPayload("PayLoad");
qp.setQueueId("ID-of-Q");
qp.setStatus("Some Status");
System.out.println(qp.serialize());
ObjectMapper om = new ObjectMapper();
QueuePayload qp2 = om.readValue("{\"payload\":\"PayLoad\",\"queueId\":\"ID-of-Q\",\"newstatus\":\"New Status\"}",
QueuePayload.class);
System.out.println(qp2.serialize());
}
That worked. The servlet doesn't
Upvotes: 4
Views: 2774
Reputation: 209042
Problem seems to be the server uses Jackson 1.x (codehaus). You are trying to use Jackson 2.x annotations (fasterxml). They don't interact. You can tell by the exception that it's a codehaus exception, meaning the older Jackson is actual used.
You can look in the server an try and find the exact version, or you can just try and use an random 1.x version (of course in a provided scope, to there's no conflict), like this one
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
<scope>provided</scope>
</dependency>
Then use org.codehaus.jackson.annotate.JsonIgnoreProperties
on the model class (not the resource class).
Upvotes: 3