How to covert JSON field name to a Java compatible property name while doing Jackson de-serialisation?

2.2k views Asked by At

I have ServerDetails pojo class.

package org.vo;

import org.codehaus.jackson.annotate.JsonProperty;

public class ServerDetails {

    private Integer serverId;
    private String server_url;

    public ServerDetails() {

    }

    public ServerDetails(Integer serverId, String server_url) {
        this.serverId = serverId;
        this.server_url = server_url;
    }

    @JsonProperty("server-id")
    public Integer getServerId() {
        return serverId;
    }


    public void setServerId(Integer serverId) {
        this.serverId = serverId;
    }

    @JsonProperty("server-url")
    public String getServer_url() {
        return server_url;
    }

    public void setServer_url(String server_url) {
        this.server_url = server_url;
    }

}

I converted the ServerDetails object to JSON using Jackson API and to customize the JSON field name I used @JsonProperty annotation. So my generated JSON is as expected like

{
   "server-id":1,
   "server-url":"http://stackoverflow.com"
}

Although in pojo class the properties are serverId and server_url but in generated JSON the fields are server-id and server-url as I have applied the @JsonProperty annotation on both propertie's getter method.

All are ok still now.

But when I am trying to covert the same JSON to Java, I am getting below error

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "server-id" (Class org.vo.ServerDetails), not marked as ignorable
 at [Source: D:\tmp\ServerDetails.json; line: 1, column: 15] (through reference chain: org.vo.ServerDetails["server-id"])
    at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:244)
    at org.codehaus.jackson.map.deser.StdDeserializer.reportUnknownProperty(StdDeserializer.java:605)
    at org.codehaus.jackson.map.deser.StdDeserializer.handleUnknownProperty(StdDeserializer.java:591)
    at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:684)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:515)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:351)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2130)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1348)
    at org.converter.JSONToJavaExample.main(JSONToJavaExample.java:16)

Somehow I am unable to figure it out what I need to do to fix this issue.I just want to get back the ServerDetails object from the generated JSON.

Below is my code for JSON to java object conversion.

import java.io.File;
import java.io.IOException;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.vo.ServerDetails;

public class JSONToJavaExample {
    public static void main(String[] args) {
        ServerDetails serverDetails = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            serverDetails = mapper.readValue(new File(
                    "D:/tmp/ServerDetails.json"), ServerDetails.class);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

I am using jackson-all-1.7.6.jar and jdk1.8.0_31.

1

There are 1 answers

0
Bacteria On BEST ANSWER

The issue has been resolved and full credit goes to both sotirios-delimanolis and staxman.Generally people like to find direct answer and not really like to going through the comments although the actual answer can be present among those comments. So this answer is dedicated for those kinds of users who like to find the direct answers.

If you are using Jackson to convert JSON to/from Java object and the Jackson API version is lower than 1.8 then you need to annotate both the getter and setter method with @JsonProperty if JSON field names and Java property names are different.

So, I have annotated both the setter methods with @JsonProperty annotation. Below is the modified code (ServerDetails.java)

@JsonProperty("server-id")
public Integer getServerId() {
    return serverId;
}

// added
@JsonProperty("server-id")
public void setServerId(Integer serverId) {
    this.serverId = serverId;
}

@JsonProperty("server-url")
public String getServer_url() {
    return server_url;
}

// added
@JsonProperty("server-url")
public void setServer_url(String server_url) {
    this.server_url = server_url;
}

If you want to avoid this extra effort, then you need to upgrade your jackson-all jar version and the version should be higher than 1.7.

Why? Why higher than 1.7?

In staxman's words

key difference is 1.7 vs 1.8: latter added code to "unify" annotations, so you do not need to add renaming for both getter and setter. With 1.7 you would need to add annotation for both, and your class only had them for one. So, not technically a bug (it was defined behavior), but missing functionality.

Hope this answer will help someone who is facing the same problem.