0

I have the following JSON being returned from a RESTful Service

{
    "Status": "Success",
    "Success": true,
    "Path": "D:\\Work\\Sites\\EKSites\\OnTrek\\privateassets\\0\\155\\156\\ceb3dc64-33ed-4e96-80a2-846120ecd9ee.pdf",
    "Timestamp": "2013-03-27T18:35:23.8997358-04:00"
}

I am trying to deserialize the JSON into this data class:

package ektron.cms.jdbc.extractors;

@JsonPropertyOrder({ "Status", "Success", "Path", "Timestamp" })
public class AssetDataResponse {

    @JsonProperty("Status")
    private String Status;

    @JsonProperty("Success")
    private Boolean Success;

    @JsonProperty("Path")
    private String Path;

    @JsonProperty("Timestamp")
    private String Timestamp;

    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("Status")
    public String getStatus() {
        return Status;
    }

    @JsonProperty("Status")
    public void setStatus(String Status) {
        this.Status = Status;
    }

    @JsonProperty("Success")
    public Boolean getSuccess() {
        return Success;
    }

    @JsonProperty("Success")
    public void setSuccess(Boolean Success) {
        this.Success = Success;
    }

    @JsonProperty("Path")
    public String getPath() {
        return Path;
    }

    @JsonProperty("Path")
    public void setPath(String Path) {
        this.Path = Path;
    }

    @JsonProperty("Timestamp")
    public String getTimestamp() {
        return Timestamp;
    }

    @JsonProperty("Timestamp")
    public void setTimestamp(String Timestamp) {
        this.Timestamp = Timestamp;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperties(String name, Object value) {
        this.additionalProperties.put(name, value);
    }
}

Following is my client code:

package ektron.common.network;
//...
ClientConfig clientConfig = new DefaultClientConfig();

clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

clientConfig.getClasses().add(JacksonJsonProvider.class);
client = Client.create(clientConfig);

WebResource webResource = 
    client.resource(
            String.format("http://%s:%d/%s","localhost",7605,"asset"));

String return =             
webResource
    .path("3f7078c4")
    .path("ceb3dc64-33ed-4e96-80a2-846120ecd9ee")
    .accept(MediaType.APPLICATION_JSON)
    .get(String.class); //This piece works and I get my JSON response as 
                        //indicated above

But if I change the above to:

AssetDataResponse resp = 
        webResource
            .path("3f7078c4")
            .path("ceb3dc64-33ed-4e96-80a2-846120ecd9ee")
            .accept(MediaType.APPLICATION_JSON)
            .get(AssetDataResponse.class); 

I get the following error:

Unrecognized field "Status" (Class ektron.cms.jdbc.extractors.AssetDataResponse), not marked as ignorable

Is there any configuration on ClientConfig that I need to make to get the deserialization working correctly? Any help on this would be very much appreciated. I am .NET developer quite new to Java and am not so familiar with the Jersey framework. I have already checked the answer from a similar question and my case is different from the case listed there.

Client side Jars

  • annotations-1.3.9.jar
  • asm-3.1.jar
  • codemodel-2.4.1.jar
  • jackson-annotations-2.1.2.jar
  • jackson-core-2.1.3.jar
  • jackson-core-asl-1.9.11.jar
  • jackson-databind-2.1.3.jar
  • jackson-jaxrs-1.9.2.jar
  • jackson-mapper-asl-1.9.11.jar
  • jackson-xc-1.9.2.jar
  • jcommander-1.30.jar
  • jersey-apache-client-1.17.jar
  • jersey-atom-abdera-1.17.jar
  • jersey-client-1.17.jar
  • jersey-core-1.17.jar
  • jersey-guice-1.17.jar
  • jersey-json-1.17.jar
  • jersey-multipart-1.17.jar
  • jersey-server-1.17.jar
  • jersey-servlet-1.17.jar
  • jettison-1.1.jar
  • jsr311-api-1.1.1.jar
  • validation-api-1.0.0.GA.jar
Community
  • 1
  • 1
Swami PR
  • 793
  • 1
  • 8
  • 15
  • I could get the above code to work only if I changed the private data members in AssetDataResponse class to public. But isn't the annotation @JsonProperty on the getters and setters supposed to be sufficient? – Swami PR Mar 28 '13 at 01:51
  • What version of Jackson is included in your client classpath? Note that your code works for me with Jersey 1.17 and Jackson 1.9. Side note, you should probably change your boolean property name to `Successful`, to match your JSON. – Perception Mar 28 '13 at 03:10
  • I was playing around with my JSON wondering if having a value Success for Status and having a property also named Status was somehow introducing the conflict. The JSON does have Success as the property and not Successful. I have updated the JSON to reflect the same. – Swami PR Mar 28 '13 at 13:03
  • My jars are as follows annotations-1.3.9.jar asm-3.1.jar codemodel-2.4.1.jar jackson-annotations-2.1.2.jar jackson-core-2.1.3.jar jackson-core-asl-1.9.11.jar jackson-databind-2.1.3.jar jackson-jaxrs-1.9.2.jar jackson-mapper-asl-1.9.11.jar jackson-xc-1.9.2.jar jcommander-1.30.jar jersey-apache-client-1.17.jar jersey-atom-abdera-1.17.jar jersey-client-1.17.jar jersey-core-1.17.jar jersey-guice-1.17.jar jersey-json-1.17.jar jersey-multipart-1.17.jar jersey-server-1.17.jar jersey-servlet-1.17.jar jettison-1.1.jar jsr311-api-1.1.1.jar validation-api-1.0.0.GA.jar – Swami PR Mar 28 '13 at 13:06
  • Woa, you have multiple versions of Jackson in your classpath. You need to eliminate all the duplicates. First, choose the version you want to use 2.1.x or 1.9.x. Then, use either the ASL or GPL versions (they are the same, just different names representing different licenses). – Perception Mar 28 '13 at 14:58
  • To compare - here are the JAR's in one of my Jersey client projects: jackson-core-asl-1.9.2.jar jackson-jaxrs-1.9.2.jar jackson-mapper-asl-1.9.2.jar jackson-xc-1.9.2.jar jersey-core-1.14.jar jersey-json-1.14.jar jersey-server-1.14.jar jersey-servlet-1.14.jar – Perception Mar 28 '13 at 15:02
  • Perception, Are the jars that you have listed the only the ones that are needed? I couldn't figure out from the names if I have duplicate jars. Could you help me out determining which of my jars are duplicates? – Swami PR Mar 28 '13 at 18:16

1 Answers1

0

I got the issue resolved. The issue was that I was importing classes from both versions of Jackson libraries as "Perception" had indicated. I can now use the latest stable version of Jackson libraries with Jersey client.

Thanks Perception for your suggestion.

Here is what my client code now looks like.

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

...
    /**
 * Wrapper class for a RESTful Service
 */
public class RestServiceWrapper
{


    public ResponseData performRequest(
                List<String> reqArgs,
                ResponseType rType,
                Class<?> dataType
                )
    {
        ResponseData data = new ResponseData();

        for(String arg: nullCheck(reqArgs))
        {
            if(StringUtils.isNotEmpty(arg))
            {
                webResource=webResource.path(arg);
            }
        }
        data.data = webResource
                .accept(MediaType.APPLICATION_JSON) //For now only JSON supported
                .get(AssetDataResponse.class);
        data.rType = ResponseType.JSON;




        return data;
    }

    protected ServiceInfo svcInfo;



    public RestServiceWrapper(ServiceInfo svcInfo) {

        ClientConfig clientConfig = new DefaultClientConfig();
        clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
        clientConfig.getClasses().add(JacksonJsonProvider.class);
        client = Client.create(clientConfig);
        this.svcInfo = svcInfo;
        this.webResource = 
                client.resource(
                        String.format("http://%s:%d/%s",svcInfo.Host,svcInfo.Port,svcInfo.EndPoint));
    }

    private static <T> Iterable<T> nullCheck(Iterable<T> iterable) {
        return iterable == null ? Collections.<T>emptyList() : iterable;
    }

    protected Client client;
    protected WebResource webResource;
}

I had to include the following line failing which I ran into the original error again

clientConfig.getClasses().add(JacksonJsonProvider.class);

the JacksonJsonProvider imported from

//jackson-jaxrs-json-provider-2.1.3.jar
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;

My jars now look like.

annotations-1.3.9.jar
asm-3.1.jar
codemodel-2.4.1.jar
jackson-annotations-2.1.2.jar
jackson-core-2.1.3.jar
jackson-databind-2.1.3.jar
jackson-jaxrs-json-provider-2.1.3.jar
jcommander-1.30.jar
jersey-apache-client-1.17.jar
jersey-atom-abdera-1.17.jar
jersey-client-1.17.jar
jersey-core-1.17.jar
jersey-guice-1.17.jar
jersey-json-1.17.jar
jersey-multipart-1.17.jar
jersey-server-1.17.jar
jersey-servlet-1.17.jar
jettison-1.1.jar
jsonschema2pojo-core-0.3.5.jar
jsr311-api-1.1.1.jar
validation-api-1.0.0.GA.jar
Swami PR
  • 793
  • 1
  • 8
  • 15