如何在执行Jackson反序列化时将JSON字段名称转换为Java兼容的属性名称?

时间:2015-06-08 15:42:26

标签: java json serialization jackson deserialization

我有ServerDetails pojo类。

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;
    }

}

我使用Jackson API将ServerDetails对象转换为JSON,并自定义我使用 @JsonProperty 注释的JSON字段名称。所以我生成的JSON就像预期的那样

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

虽然在pojo类中属性是serverId和server_url但是在生成的JSON中,字段是server-id和server-url,因为我在两个属性的getter方法中都应用了@JsonProperty注释。

现在一切都还好。

但是当我试图将相同的JSON转换为Java时,我收到的错误

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)

不知怎的,我无法弄明白我需要做些什么来解决这个问题。我只是想从生成的JSON中获取ServerDetails对象。

下面是我的JSON到java对象转换的代码。

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();
        }

    }
}

我正在使用 jackson-all-1.7.6.jar jdk1.8.0_31

1 个答案:

答案 0 :(得分:2)

此问题已得到解决,并且sotirios-delimanolisstaxman都可以获得完全的功劳。一般来说,人们喜欢找到直接答案而不是真的想通过评论,尽管实际答案可能存在于那些评论。所以这个答案专门针对那些喜欢找到直接答案的用户。

如果您使用Jackson将JSON转换为/从Java对象转换并且Jackson API版本低于1.8 那么您需要使用@JsonProperty <注释 getter和setter方法/ strong>如果JSON字段名称和Java属性名称不同。

所以,我用@JsonProperty注释注释了setter方法。下面是修改后的代码(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;
}

如果您想避免这种额外的努力,那么您需要升级 jackson-all jar版本,版本应高于1.7

为什么呢?为什么高于1.7?

用staxman的话来说

  

关键区别是1.7 vs 1.8:后者添加了“统一”注释的代码,因此您不需要为getter和setter添加重命名。使用1.7时,您需要为两者添加注释,而您的类只有一个注释。因此,技术上不是一个错误(它是定义的行为),但缺少功能。

希望这个答案可以帮助那些面临同样问题的人。