2013-10-15 93 views
11

ObjectMapperreadValue(InputStream in, Class<T> valueType)函數需要該類。但是如果我在內部傳遞的類有一些接口作爲數據成員,我該如何使用它。如何使用Jackson的objectMapper對接口字段進行反序列化?

雖然我能理解這個異常背後的原因,因爲傑克遜沒有獲得傳遞類的內部接口的具體類,但我的問題是如何解決它? 那我該如何反序列化呢?我想反序列化的類是:

class BaseMetricImpl<N> implements Metric<N> { 
    protected MetricValueDescriptor descriptor; 
} 

這裏MetricValueDescriptor是一個接口,所以這給了我以下錯誤: -

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of MetricValueDescriptor, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information 
at [Source: [email protected]; line: 1, column: 2] (through reference chain: SingleValueMetricImpl["descriptor"]) 
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) 
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:624) 
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:115) 
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375) 
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308) 
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2793) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1989) 
+0

你可以更新你的示例代碼並完成錯誤堆棧跟蹤。 – vels4j

+0

@ vels4j我編輯了這個問題,把小代碼示例和異常 – Naman

回答

27

傑克遜顯然無法構建MetricValueDescriptor對象,因爲它是一個接口。你需要在你的json和ObjectMapper中有更多的信息來告訴傑克遜如何從中構建一個對象。這裏是一個辦法做到這一點,假設MVDImpl是實現MetricValueDescriptor的具體類:

你可以告訴傑克遜穿過JSON本身領域所需的類型信息,說"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。它非常全面地涵蓋了這個主題並附有示例。所以如果你需要更多的定製,你一定要閱讀它。

+2

我面臨同樣的問題,但是,'超級'不屬於我,它不能被修改。在那種情況下,我們如何讓'傑克遜'的地圖到右邊的'子類'? – lvarayut

+1

@lvarayut您可以使用[Jackson Mixin Annotations](http://wiki.fasterxml.com/JacksonMixInAnnotations)將註釋添加到不可修改的類。 – mucaho

+0

另一種方式(更多參與)是使用所謂的「默認類型」,通過「ObjectMapper」啓用。它將允許啓用包含類別信息的類別的類別,而無需註釋。默認情況下,有幾種選擇,如「所有非具體類型」,「所有非最終類型」,但您也可以實施自己的策略。 – StaxMan

相關問題