【问题标题】:Jackson deserialize List<abstractClass> of classImpl objectsJackson 反序列化 classImpl 对象的 List<abstractClass>
【发布时间】:2014-05-07 05:16:18
【问题描述】:

我有一个抽象超类 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 { 

但这没有用。这有什么例子吗?如何告诉对象映射器将我的注释用于类?任何这方面的例子都会很棒。

【问题讨论】:

  • 也许this 会有所帮助。

标签: java json serialization jackson


【解决方案1】:

你做得对,但Jackson 不检查集合中的元素。请看我对这个问题的回答:Error serializing Typed collection with 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>>() {}));

【讨论】:

  • 感谢您的帮助。看来我有一个更大的问题。我这样做:new B(),添加一些东西,然后 writeValueAsString,我看到 @class 没有被添加到 JSON 中。其他事情是非常错误的......
  • 您能否更新您的问题并提供更多信息(示例源代码、结果 JSON 等)。
【解决方案2】:

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

public class AList extends ArrayList<A> { }

并通过它;它确保有足够的类型信息可用于序列化和反序列化(因为问题是序列化几乎总是成功,因为类型可从 Objects 获得;反序列化则不然)。

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

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

但是如果您需要其他子类型,则需要使用 @JsonTypeInfo 注释 A,并使其使用 Java 类名或使用 @JsonTypeName 指定子类的类型名称(加上基类中的 @JsonSubTypes让杰克逊找到他们)。

【讨论】:

  • 假设我用 @JsonTypeInfo 注释 A 就像我在示例中所做的那样。你能给我一个具体的例子来说明如何使用 Java 类名来做 B 吗?
猜你喜欢
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2014-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多