当前位置: 首页 > 知识库问答 >
问题:

Jackson反序列化classImpl对象的列表

慕容嘉荣
2023-03-14

我有一个抽象的超类A,我有几个具体的子类B,C,D

在序列化方面,我执行以下操作:

List<A> list = new ArrayList<A>();
B b = new B();
C c = new C();
D d = new D();
list.add(b);
list.add(c);
list.add(d);
json = mapper.writeValueAsString(list);

没问题。我现在想反序列化这个。我知道我不能实例化一个抽象类,那么这是如何实现的呢?

这不起作用:

list = mapper.readValue(json,new TypeReference<List<A>>() {});

编辑:我把这个添加到我的抽象超类中:(仍然没有运气)

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
public abstract class A {

再次编辑:我现在遇到以下错误:

Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id

看看JSON,@class不在那里。我怎样才能做到?我试过:

@JsonDeserialize(as=B.class)
public class B extends A { 

但这并没有奏效。有这方面的例子吗?如何告诉对象映射器对类使用我的注释?任何这样的例子都会很棒。

共有2个答案

刘德义
2023-03-14

针对Java类型擦除问题(不幸的是,问题与此比Jackson更相关)的常见解决方法是使用自定义子类型,如:

public class AList extends ArrayList<A> { }

并传递这个;它确保有足够的类型信息可用于序列化和反序列化(因为问题是序列化几乎总是成功的,因为类型可从对象获得;反序列化不是这样)。

除此之外,还有从抽象类型A映射到子类型(s)的问题。

如果您只有一个实现,您可以使用SimpleMoules和方法addAbstractType映射(A. class, B. class)来指示要使用的默认实现。

但是如果您需要其他子类型,您确实需要用@JsonTypeInfo注释A,并且使用Java类名或使用@JsonTypeName(加上@JsonSubTypes在基类中让Jackson找到它们)。

仲孙奇
2023-03-14

您这样做是正确的,但是Jackson不检查集合中的元素。请参阅我对这个问题的回答:用Jackson序列化类型化集合时出错。您必须使用特殊的集合,为此Jackson将使用自定义序列化器。

简单用法:

List<A> list = new JacksonList<>();
list.add(new B());
list.add(new C());

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);
System.out.println(json);
System.out.println(mapper.readValue(json, new TypeReference<List<A>>() {}));
 类似资料:
  • 我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢

  • 我有以下控制器: 使用以下请求对象: 当帖子通过并查看我得到的对象时,有效负载列表中有LinkedHashMap对象,而不是我的DTO类型的对象。 如何让Spring jackson将JSON转换为我的DTO对象。请记住,我计划对其他对象列表重用包装器响应DTO,这就是我使用通用列表(List)的原因。 这是我正在尝试的JSON。

  • 主要内容:1 编写核心类,2 运行测试本文讲解如何将一个Java对象序列化为一个json文件,然后读取该json文件读取回对象。在下面的示例中,我们创建Student类。使用Jackson存储到一个student.json文件,该文件拥有Student对象的JSON表示形式。 1 编写核心类 MainApp: 2 运行测试

  • 问题内容: 我需要从Redis保存和加载对象。 该对象包含GrantedAuthority列表(除其他外),它是一个接口: Jackson成功地序列化了该对象,但未能反序列化,但有以下例外: 我知道我可以通过添加以下内容来指定类型: 但是在这种情况下我无法做到这一点,因为the 是Spring的接口,我无法更改它。 序列化的json是: } 摘要只能用填充。 所以我尝试了: 仍然没有运气。 问题答

  • 我需要从 redis 保存和加载对象。 该对象包含GrantedAuthority列表(以及其他内容),它是一个接口: Jackson 成功序列化了该对象,但未能对其进行反序列化,但有以下异常: 我知道我可以通过添加来指定类型: 但在这种情况下我不能这样做,因为是Spring的一个接口,我不能更改它。 序列化的json是: } 摘要只充满了。 所以我尝试了: 但仍然没有运气。

  • 问题内容: 我需要从redis保存和加载对象。 该对象包含GrantedAuthority列表(除其他外),它是一个接口: Jackson成功地序列化了该对象,但是未能反序列化该对象,但有以下例外: 我知道可以通过添加以下内容来指定类型: 但是在这种情况下我无法做到这一点,因为the 是Spring的接口,我无法更改它。 序列化的json是: } 摘要只能用填充。 所以我尝试了: 仍然没有运气。