杰克逊在序列化时不包括字段的类型信息

时间:2015-11-21 07:14:59

标签: java json jackson fasterxml

我正在尝试使用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()));
}
}

杰克逊转换的json是

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

请注意,它不包含字段' a'的类型信息。只序列化A时会包含类型信息。

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

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

2 个答案:

答案 0 :(得分:4)

看起来你非常接近,你需要添加的是一种告诉jackson如何处理你的界面类型的方法。

@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"}}

希望它有所帮助,

JoséLuis

答案 1 :(得分:0)

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

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

com.fasterxml.jackson.databind.ObjectMapper

但我已导入 jackson-mapper-asl.jar

org.codehaus.jackson.map.ObjectMapper