stwissel
stwissel

Reputation: 20384

Ignoring incoming json elements in jax-rs

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

Answers (1)

Paul Samsotha
Paul Samsotha

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

Related Questions