如何使用Jackson的objectMapper反序列化接口字段?

时间:2013-10-15 11:15:28

标签: java json jackson

ObjectMapper的{​​{1}}函数需要Class。但是如果我在内部传递的类有一些接口作为数据成员,我该如何使用它。

虽然我可以理解这个异常背后的原因,因为Jackson没有得到传递类的内部接口的具体类,但我的问题是如何解决它? 我该如何反序列化呢?我试图反序列化的类是:

readValue(InputStream in, Class<T> valueType)

这里class BaseMetricImpl<N> implements Metric<N> { protected MetricValueDescriptor descriptor; } 是一个接口,所以这给了我以下错误: -

MetricValueDescriptor

2 个答案:

答案 0 :(得分:42)

杰克逊显然无法构造MetricValueDescriptor对象,因为它是一个接口。您需要在json和ObjectMapper中获得其他信息,以告诉jackson如何构造一个对象。这是一种方法,假设MVDImpl是实现MetricValueDescriptor的具体类:

您可以通过json本身的字段告诉Jackson所需的类型信息,比如说"type"。为此,您需要在界面中使用JsonTypeInfoJsonSubTypes注释。例如,

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @Type(value = MVDImpl.class, name = "mvdimpl") })
interface MetricValueDescriptor
{
   ...
}

您还需要在json中添加"type":"mvdimpl"字段。

我将指向official doc以获取更多信息,但后来我发现了一个涵盖此主题的优秀博客 - Deserialize JSON with Jackson。它非常全面地并通过示例介绍了这个主题。所以如果你需要更多的自定义,你一定要阅读它。

答案 1 :(得分:3)

我认为它是两种方法之一,但是它们都需要您手动创建一个实现您的接口的具体类。

  1. 使用@Hari Menon的答案并使用@JsonSubTypes。如果您可以引入类型字段或其他内容来触发要使用的实现,则此方法有效。
  2. 使用@JsonDeserialize告诉杰克逊默认情况下使用什么具体类。
@JsonDeserialize(as = MVDImpl.class)
interface MetricValueDescriptor
{
   ...
}

这里有更详尽的解释:https://zenidas.wordpress.com/recipes/jackson-deserialization-of-interfaces/

文档:https://fasterxml.github.io/jackson-databind/javadoc/2.8/com/fasterxml/jackson/databind/annotation/JsonDeserialize.html