序列化后,Jackson序列化程序不显示jsonInfoType

时间:2015-07-10 22:09:47

标签: java json serialization jackson

我有一个基类和一个派生类,如下面的

@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS,
include =JsonTypeInfo.As.PROPERTY, property = "_type")
@JsonSubTypes({ @JsonSubTypes.Type(value = BaseClass.class,
name = "BaseClass")})    
public class BaseClass{
    private String a;
}


public class DerivedClass extends BaseClass{
    private String b;
}

当我序列化BaseClass列表或DerivedClass列表时,我在json中找不到'_type'属性。但是如果我序列化一个BaseClass或Derived类的实例,我可以看到'_type'属性。

这是我的Serializer代码。

public void serialize() throws Exception {

    List<DerivedClass> bs = new ArrayList<DerivedClass>();
    bs.add(new DerivedClass());
    bs.add(new DerivedClass());
    String json = new ObjectMapper().writeValueAsString(bs);
    LOG.debug(json);
}

1 个答案:

答案 0 :(得分:1)

问题在于,由于Java Type Erasure,所有Jackson看到的都是List<Object>,关于类型。由于Object没有@JsonTypeInfo,因此不认为需要类型信息 - 所有值必须使用相同的逻辑基类型,因为在反序列化期间没有实例,并且必须使用静态已知的类型作为基线

那么你如何解决这个问题?

首先:我的建议是始终使用简单的非通用POJO作为根值,并完全避免这个问题。从POJO到达的任何List值属性都将具有完整的类型信息;根值不。因此,我避免直接​​序列化ListMap以及通用(参数化)POJO。

但是,如果您仍想解决更难的问题,那么它也是可行的。两种主要方式:

第一种方法:创建一个便利类,如:

public class ListOfBase extends ArrayList<BaseClass> { }
ListOfBase myList = new ListOfBase();
myList.add(...);

它将按预期工作,具有类型信息

第二种方法:强制使用特定的基本类型,通过ObjectWriter:类似于:

ObjectWriter w = mapper.writerFor(new TypeReference<List<BaseClass>>() { });
String json = w.writeValueAsString(myList);

但是(不幸的是)这会强制使用BaseClass来获取实际内容,而不仅仅是输入信息。因此,不包括任何实现类的属性。

实际上,还有第三种选择:使用Java数组,而不是集合。 数组是强类型的,所以这也可以工作:

BaseClass[] stuff = new BaseClass[] { value1, value2 };

因为类型信息被保留,与通用List s不同。