为什么杰克逊多态序列化在列表中不起作用?

编程入门 行业动态 更新时间:2024-10-26 22:24:02
本文介绍了为什么杰克逊多态序列化在列表中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

杰克逊正在做一些真正奇怪的事情,我找不到任何解释。我正在进行多态序列化,当一个对象独立时它可以很好地工作。但是,如果将相同的对象放入列表并对列表进行序列化,则会删除类型信息。

Jackson is doing something truly bizarre and I cannot find any explanation for it. I'm doing polymorphic serialization and it works perfectly when an object is on its own. But if you put the same object into a list and serialize the list instead, it erases the type information.

它丢失类型信息的事实会导致人们怀疑类型擦除。但是在序列化列表的内容期间会发生这种情况;杰克逊所要做的就是检查它正在序列化的当前对象以确定它的类型。

The fact that it's losing type info would lead one to suspect type erasure. But this is happening during serialization of the contents of the list; all Jackson has to do is inspect the current object it's serializing to determine its type.

我用Jackson 2.5.1创建了一个例子:

I've created an example using Jackson 2.5.1:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.List; public class Test { @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY) @JsonSubTypes({ @Type(value = Dog.class, name = "dog"), @Type(value = Cat.class, name = "cat")}) public interface Animal {} @JsonTypeName("dog") public static class Dog implements Animal { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @JsonTypeName("cat") public static class Cat implements Animal { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public static void main(String[] args) throws JsonProcessingException { List<Cat> list = new ArrayList<>(); list.add(new Cat()); System.out.println(new ObjectMapper().writeValueAsString(list)); System.out.println(new ObjectMapper().writeValueAsString(list.get(0))); } }

这是输出:

[{"name":null}] {"@type":"cat","name":null}

如您所见,当对象在列表中时,Jackson不会添加类型信息。有谁知道为什么会发生这种情况?

As you can see, Jackson is not adding the type information when the object is in a list. Does anyone know why this is happening?

推荐答案

讨论了发生这种情况的各种原因在此处和此处。我不一定同意这些原因,但杰克逊,因为类型擦除,不会关闭蝙蝠知道元素的类型列表(或 Collection 或 Map )包含。它选择使用不能解释您的注释的简单序列化器。

The various reasons for why this happens are discussed here and here. I don't necessarily agree with the reasons, but Jackson, because of type erasure, doesn't off the bat know the type of elements the List (or Collection or Map) contains. It chooses to use a simple serializer that doesn't interpret your annotations.

您可以在这些链接中建议两个选项:

You have two options suggested in those links:

首先,您可以创建一个实现 List< Cat> 的类,适当地实例化并序列化实例。

First, you can create a class that implements List<Cat>, instantiate it appropriately and serialize the instance.

class CatList implements List<Cat> {...}

泛型类型参数 Cat 没有丢失。 Jackson可以访问它并使用它。

The generic type argument Cat is not lost. Jackson has access to it and uses it.

其次,您可以实例化并使用 ObjectWriter 作为类型列表与LT;目录> 。例如

Second, you can instantiate and use an ObjectWriter for the type List<Cat>. For example

System.out.println(new ObjectMapper().writerFor(new TypeReference<List<Cat>>() {}).writeValueAsString(list));

将打印

[{"@type":"cat","name":"heyo"}]

更多推荐

为什么杰克逊多态序列化在列表中不起作用?

本文发布于:2023-11-06 13:20:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1563800.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:杰克逊   不起作用   序列化   多态   列表中

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!