java - 为什么 Jackson 多态序列化在列表中不起作用?

标签 java json serialization jackson

Jackson 正在做一些非常奇怪的事情,我找不到任何解释。我正在做多态序列化,当一个对象独立时它工作得很好。但是,如果您将相同的对象放入列表中并序列化该列表,它会删除类型信息。

它正在丢失类型信息这一事实会让人怀疑类型删除。但这是在序列化列表的内容期间发生的; Jackson 所要做的就是检查它正在序列化的当前对象以确定其类型。

我使用 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 没有添加类型信息。有谁知道为什么会这样?

最佳答案

讨论了发生这种情况的各种原因 herehere .我不一定同意其中的原因,但是 Jackson,由于类型删除,不会马上知道 List 元素的类型(或 CollectionMap )包含。它选择使用不解释您的注释的简单序列化程序。

这些链接中有两个建议选项:

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

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

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

其次,您可以实例化并使用 ObjectWriter对于类型 List<Cat> .例如

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

将打印

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

关于java - 为什么 Jackson 多态序列化在列表中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34193177/

相关文章:

javascript - 使用 JSON.stringify 进行深度比较和克隆是否合适?

c# - 如何从 Web API JSON 响应派生 C# 动态对象?

java - 使用 ArrayList 填充 ListFragment

java - 如何在不使用 java 中的递归或循环的情况下查找阶乘?

java - UTF-8 和 ISO-8859-1 不适用于 Java 中的欧洲字符集解码

python - UUID 不是 JSON 可序列化的(转储数据)

java - Jackson 中自定义序列化的公认做法是什么?

java - Eclipse、Maven 项目上线程 "main"java.lang.NoClassDefFoundError 中出现异常

java - 使用Jackson解析和未命名数组

ios - 在 tableView 中显示用户评论