Java Jackson序列化程序不';序列化后不显示JSONInfo类型

Java Jackson序列化程序不';序列化后不显示JSONInfo类型,java,json,serialization,jackson,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 Stri

我有一个基类和一个派生类,如下所示

@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;
}
当我序列化基类列表或DerivedClass列表时,我在json中找不到“\u type”属性。但如果我序列化基类或派生类的单个实例,我可以看到'\u type'属性

这是我的序列化程序代码

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);
}
public void serialize()引发异常{
列表bs=新的ArrayList();
添加(新的DerivedClass());
添加(新的DerivedClass());
字符串json=newObjectMapper().writeValueAsString(bs);
LOG.debug(json);
}

问题在于,由于Java类型擦除,Jackson看到的都是关于类型的
列表。由于
对象
没有
@JsonTypeInfo
,它认为不需要类型信息——所有值都必须使用相同的逻辑基类型,因为在反序列化过程中没有实例,静态已知类型必须用作基线

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

第一:我的建议是始终使用简单的、非泛型的POJO作为根值,并完全避免这个问题。从POJO访问的任何
列表
值属性都将具有完整的类型信息;根值不存在。因此,我避免直接序列化
List
s和
Map
s,以及通用(参数化)POJO

然而,如果你仍然想解决更难的问题,这也是可行的。主要有两种方式:

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

public class ListOfBase extends ArrayList<BaseClass> { }
ListOfBase myList = new ListOfBase();
myList.add(...);
但是(不幸的是)这也将强制对实际内容使用
BaseClass
,而不仅仅是类型信息。因此,不包括实现类的任何属性

实际上,还有第三种选择:使用Java数组,而不是集合。 数组是强类型的,因此这也适用于:

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

由于保留了类型信息,因此与泛型
List
s不同。

我尝试了堆栈溢出的所有解决方案。看起来我也在做类似的事情,但不知道为什么我不能得到类型。我不想使用mapper.writerWithType()。这不足以重现您的问题:请包含用于序列化的代码。还有一些常见的问题,例如尝试序列化多态值的
列表
,其中Java类型擦除会导致问题。但是如果没有代码,就不可能说出问题所在。@StaxMan我添加了代码来序列化它。这正是我的设想@如果我说List List=newarraylist(),那么statxmandoes就是这个工作;否:类型擦除意味着Java没有运行时泛型类型的概念;只有
Class
声明包含它们。这就是
TypeReference
工作的原因:它创建了包含类型声明的实际匿名类。仅仅实例化并不会保留额外的类型信息:底层物理类是相同的
ArrayList
,它本身是泛型的,实际的类型参数丢失(它们只存在于源代码中,字节码只包含必要的强制转换)。
BaseClass[] stuff = new BaseClass[] { value1, value2 };