Jackson: 数组中缺少@JsonTypeInfo

7

我发现了Jackson JSON处理库的一些奇怪行为,我想知道这是故意的还是一个错误。请看下面的代码:

@JsonTypeInfo(use = Id.NAME)
public class Nut {}

ObjectMapper mapper = new ObjectMapper();

Nut nut = new Nut();
Object object = new Nut();
Nut[] nuts = new Nut[] { new Nut() };
Object[] objects = new Object[] { new Nut() };

System.out.println(mapper.writeValueAsString(nut));
System.out.println(mapper.writeValueAsString(object));
System.out.println(mapper.writeValueAsString(nuts));
System.out.println(mapper.writeValueAsString(objects));

输出:

{"@type":"Nut"}
{"@type":"Nut"}
[{"@type":"Nut"}]
[{}]

我期望(并希望)的是以下内容:
{"@type":"Nut"}
{"@type":"Nut"}
[{"@type":"Nut"}]
[{"@type":"Nut"}] // <<< type information included

我有遗漏吗,还是应该提交一个错误报告?
1个回答

4
这是预期行为。在序列化对象图时,Jackson使用对象的声明类型确定要包含哪些类型信息。 objects中的元素声明类型为Object,你没有告诉Jackson包含任何类型信息。
Jackson仅查看writeValueAsString的顶级参数的运行时类型,因为方法参数的类型为Object。在Java中,无法知道作为方法参数传递的对象的声明类型(即使有泛型,也由于类型擦除而不可能),因此您的前两个示例(writeValueAsString(nut)writeValueAsString(object)实际上是相同的)。
更多信息请参见:http://jackson-users.ning.com/forum/topics/mapper-not-include-type-information-when-serializing-object-why

非常感谢您的解释,特别是指出前两个示例在行为上是相同的,因为我还不太清楚。是否有可能强制在容器内使用实际类型?通过混入注释对象类(Object class)并不符合我的需求(也许我应该开一个后续问题来呈现我的实际问题背景)。 - nutlike
在我提供的讨论中,Tatu说:“[Jackson] 必须使用声明类型,以确保使用相同的类型信息设置;否则信息可能会基于每个元素而异,并且在反序列化期间无法确定此区别”,因此我认为您唯一的选择是为对象启用类型信息(或在ObjectMapper上启用enableDefaultTyping),或更改数组的类型。如果您打开后续问题,请确保解释您的用例以及为什么您不能执行这两个操作之一。 - Miles
您可能希望启用所谓的“默认类型”,它可用于包含java.lang.Object条目的类型信息(或其他无法或不想注释的类组)。 - StaxMan
我之前尝试了这两个建议(现在再次尝试以确保),但都无法使其工作-我在https://dev59.com/fG3Xa4cB1Zd3GeqPkOoI上开了一个后续问题。无论如何,还是谢谢你的努力。 - nutlike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接