【问题标题】:How to covert JSON field name to a Java compatible property name while doing Jackson de-serialisation?如何在进行杰克逊模具序列化时将 JSON 字段名称转换为 Java 兼容的属性名称?
【发布时间】:2015-08-23 04:19:39
【问题描述】:

我有 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.jarjdk1.8.0_31

【问题讨论】:

  • 这对我来说很好。请发布 MCVE。也就是说,将您的示例更改为首先将对象序列化为 String 值,向我们展示 String 值,然后直接反序列化它(而不是在 File 中),并向我们展示结果(和代码)。
  • 对我也很好。您使用的是哪个版本的 Jackson?
  • 升级到 1.9.13 或升级到 Jackson 2。
  • @Arin 的关键区别是 1.7 和 1.8:后者添加了代码以“统一”注释,因此您不需要为 getter 和 setter 添加重命名。使用 1.7,您需要为两者添加注释,而您的班级只有一个。因此,从技术上讲,它不是错误(它是定义的行为),而是缺少功能。
  • @StaxMan。是的。我已经在 getter 和 setter 上应用了 @JsonProperty 注释,并针对 1.7.6 进行了测试。它工作正常。感谢您指出实际差异。

标签: java json serialization jackson deserialization


【解决方案1】:

问题已得到解决,sotirios-delimanolisstaxman 都得到了充分的肯定。通常人们喜欢直接找到答案,而不是真的喜欢通过 cmets,尽管实际答案可能存在于这些 cmets 中。所以这个答案是专门为那些喜欢直接找到答案的用户准备的。

如果您使用 Jackson 将 JSON 转换为 Java 对象/从 Java 对象转换并且 Jackson API 版本低于 1.8 那么您需要使用 @JsonProperty 注释 getter 和 setter 方法 如果 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 与 1.8:后者添加了代码以“统一”注释,因此您无需为 getter 和 setter 添加重命名。使用 1.7,您需要为两者添加注释,而您的班级只有一个。因此,从技术上讲,它不是错误(它是定义的行为),而是缺少功能。

希望这个答案能帮助遇到同样问题的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2021-11-08
    • 2021-08-11
    • 2017-09-02
    • 2020-11-30
    • 2023-04-07
    相关资源
    最近更新 更多