JsonProperty will serialize but not deserialize

1.6k Views Asked by At

In short, I am attempting to write an integration test with rest-assured for a rest service I wrote. My issue is that when the server attempts to deserialize the JSON I get the error with field "meta-data" not marked as ignorable. I must process this field, which also means (to the best of my knowledge) I cannot mark it as ignorable. Yes, I have "turned it off and on again". Turned off apache, manually deleted my war and exploded files, redeployed, examined the contents to see updates, turned server back on.

DISCLAIMERS: If I may not upgrade versions, but I could possibly downgrade. For example, I could use Jackson 1.0 instead of Jackson 2.0. I have also simplified my problem for sake of brevity. I can't change the JSON structure in any way. I've seen a similar Thread related to Spring, but I'm not using Spring.

This is just a fragment of the whole JSON object. If I can get meta-data and its two attributes working, I can apply what I learned to the rest of the problem. Thanks!

My JSON

{
  "meta-data" : {
    "submission-time" : "06.12.2016",
    "workflow-reference" : "TEST-WORKFLOW"
  }
}

My JSON POJO

package com.company.group.project.module.shared.json;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Feature;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class JsonMandateRequest {

    @JsonProperty("meta-data")
    private MetaData metadata;

    public MetaData getMetadata() {
        if (null == metadata) {
            metadata = new MetaData();
        }
        return metadata;
    }

    public void setMetadata(final MetaData metadata) {
        this.metadata = metadata;
    }

    @JsonSerialize
    public static class MetaData {

        @JsonProperty("submission-time")
        private String timestamp;

        @JsonProperty("workflow-reference")
        private String workflow;

        public String getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(final String timestamp) {
            this.timestamp = timestamp;
        }

        public String getWorkflow() {
            return workflow;
        }

        public void setWorkflow(final String workflow) {
            this.workflow = workflow;
        }

    }
}

My Rest Service declaration (I know the path works. That is not what is broken.)

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
public Response uploadFile(final JsonMandateRequest reminders) {
    return buildResponse(reminders, PROCESSOR_UPLOAD_MANDATE);
}

Here is the code that produces my JSON string. It works, but I'm including it in case it benefits the reader in some way.

public static String writeObject(final Object obj) throws IOException
{
    ObjectMapper mapper = new ObjectMapper();
    mapper = mapper.disable(
            DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
    return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}

My Integration Test code snippet

    Response r = given()
            .contentType(ContentType.JSON)
            .body(jsonString)
            .when().post(url);
    System.out.println("Response from " + url + "(" + r.getStatusCode() + ")");
    System.out.println(r.asString());

Output:

Response from http://localhost:8080/application/rest/path(400)
Unrecognized field "meta-data" (Class com.company.group.project.module.shared.json.JsonMandateRequest), not marked as ignorable
 at [Source: org.apache.catalina.connector.CoyoteInputStream@b60721a; line: 2, column: 18] (through reference chain: com.company.group.project.module.shared.json.JsonMandateRequest["meta-data"])
Completed com.company.group.project.module.services.rest.InstructionServiceIT#testLifecycle(InstructionServiceIT.java:95)

My servlet container is tomcat 7.0.73 Here are snippets from my pom.xml which show the other versions of software I'm using.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-json</artifactId>
    <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.8.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.3</version>
</dependency>
1

There are 1 best solutions below

0
On BEST ANSWER

Thanks to Chris Hinshaw for pointing me in the right direction. The version of jersey I'm using doesn't support the version of Jackson I'm using. I cannot step up to a newer version of Jersey, so I had to step down from Jackson 2 to Jackson 1. I left the old stuff commented out for the benefit of the reader.

  <!--<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.8.3</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.4</version>
  </dependency>-->
  <dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-all</artifactId>
    <version>1.9.0</version>
  </dependency>

Apparently, Jersey 1.9.1 is compatible with Jackson 1.9.0, at least in my case.

My new imports in JsonMandateRequest look like this.

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;

Hope this helps someone!