【问题标题】:Jackson does not include type info for fields while serializationJackson 在序列化时不包括字段的类型信息
【发布时间】:2015-11-21 07:14:58
【问题描述】:

我正在尝试使用 jackson 2.6.3 将对象序列化为 json 我想在序列化的 json 中包含类型信息。这不适用于嵌套在此类中的成员。

这是测试代码。

public class Test {

@JsonSubTypes({ @JsonSubTypes.Type(value = ConcreteA.class)})
interface A {

}
@JsonTypeInfo( use=JsonTypeInfo.Id.CLASS)
class ConcreteA implements A {

}

@JsonSubTypes({ @JsonSubTypes.Type(value = ConcreteB.class)})
interface B {

}
@JsonTypeInfo( use=JsonTypeInfo.Id.CLASS)
class ConcreteB implements B {
    A a;
    public A getA() {
        return a=new ConcreteA();
    }
}

@org.junit.Test
public void testSerialisation() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    System.out.println(objectMapper.writeValueAsString(new ConcreteB()));
}
}

jackson正在转换的json是

{"@class":"Test$ConcreteB","a":{}}

请注意,它不包括字段“a”的类型信息。仅序列化 A 时确实包含类型信息。

{"@class":"Test$ConcreteA"} 

更新: 这是jackson dev对该问题的解释和解决方案 https://github.com/FasterXML/jackson-databind/issues/1015

【问题讨论】:

  • 为什么在序列化 B 时需要 'a' 的类型信息?当您反序列化为“B”时,“a”的类型将由 B 给出。
  • A 是一个接口,可以有很多实现。如果没有类型信息,你怎么知道要反序列化哪种类型?
  • 我现在看到了问题,也解决了问题。

标签: java json jackson fasterxml


【解决方案1】:

看来你已经很接近了,你需要添加的只是一种告诉杰克逊如何处理你的接口类型的方法。

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "@class")
@JsonSubTypes({
        @JsonSubTypes.Type(value = ConcreteA.class)})
interface A {
}

因此,将@JsonTypeInfo 添加到您的界面将在您可以配置为您期望的属性中添加类型信息,在这种情况下我选择了@class

我从示例中得到的 Json 输出:

{"@class":"com.company.jackson.Test$ConcreteB","a":{"@type":"Test$ConcreteA"}}

希望对你有帮助,

何塞·路易斯

【讨论】:

  • 只将@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS) 添加到A 中。谢谢指点。
  • 很高兴听到它有效并帮助了您,请您接受答案吗?谢谢!
  • 我想在“@class”中有完全限定的类名。上述解决方案将类型名称放在“@class”中。使用 JsonTypeInfo.Id.CLASS 代替的是接口的类名而不是实现。
  • 当我们在数组中应用它时,Jackson 不会对生成的 JSON 应用“@class”。请问有什么建议吗?
【解决方案2】:

您还必须将 visible 属性设置为 true,否则它可能仍然无法正常工作(我的情况)。我将增强上述答案之一:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "@class",
        visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ConcreteA.class)})
interface A {
}

【讨论】:

    【解决方案3】:

    我也遇到过同样的问题。 我导入了错误的 ObjectMapper 类。

    理想情况下,它应该是 jackson-databind.jar

    com.fasterxml.jackson.databind.ObjectMapper
    

    但是我已经导入了 jackson-mapper-asl.jar

    org.codehaus.jackson.map.ObjectMapper
    

    【讨论】:

      猜你喜欢
      • 2014-10-06
      • 2018-08-10
      • 2017-03-09
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多