2012-01-03 80 views
4

我有幾個擴展LinkedHashMap<String, Object>的模型類:它們定義包含Map的get和put方法的getter和setter。我試圖用Jackson(帶RESTEasy)序列化這些類的實例,但Jackson拒絕關注我的獲得者,這些獲得者用@JsonProperty註釋。相反,它只是序列化背景地圖的鍵值對。我嘗試使用@JsonAutoDetect來禁用所有方法和字段的自動檢測,但這並沒有改變任何內容。有沒有一種方法可以防止Jackson自動序列化一個Map,或者是否必須創建不延伸LinkedHashMap<String, Object>的新模型類?傑克遜 - 序列化時忽略映射超類

回答

7

我具有延伸LinkedHashMap<String, Object>幾個模型類:它們定義getter和setter其包裝Map的get和put方法

這是當使用繼承一個典型的例子:你他發現其他一些代碼(即傑克遜)正在將你的類視爲其超類的一個實例,而這並不是你想要的。在這些(以及一般情況下)的情況下,通常使用組合而不是繼承。

我建議您將模型類重寫爲包含的地圖,而不是擴展一個。您比方式獲得更多的控制,並且最終的模型不易變脆。如果您需要將您的模型視爲Map,然後實施呈現該視圖的asMap方法(或類似的東西)。

+1

感謝您的回覆,skaffman。我實際上正在考慮轉向基於構圖的方法。 'LinkedHashMap'實際上不是我模型類的直接超類;相反,它們擴展了MongoDB的'BasicDBObject',這使我可以輕鬆地堅持它們。但是,我可能會嘗試將這些對象用於太多目的。添加到DBObject()和fromDBObject()方法應該可以工作。不過,我仍然好奇是否有辦法阻止Jackson執行默認的「Map」序列化。有沒有辦法禁用特定類型的序列化程序? – gilby 2012-01-03 22:36:27

9

我同意@ skaffman的迴應。但是如果你不能很容易地改變繼承結構,那麼可能有辦法解決這個問題。

一種可能性是,如果你有一個定義getter/setter方法的接口,你可以添加

@JsonSerialize(as=MyInterface.class) 
@JsonDeserialize(as=MyInterface.class) 

這將迫使傑克遜只用不管是通過特定的接口使用。

自定義序列化器/反序列化器也是一種可能性,但這是相當多的工作。

2

您可以實現自己的org.codehaus.jackson.map.DeserializerProvider延伸傑克遜的org.codehaus.jackson.map.deser.StdDeserializerProvider和覆蓋方法_createDeserializer

import org.codehaus.jackson.map.SerializerProvider; 
import org.codehaus.jackson.map.deser.StdDeserializerProvider; 
import org.codehaus.jackson.map.DeserializationConfig; 
... 

class MyDeserializerProvider extends StdDeserializerProvider { 

    @Override 
    protected JsonDeserializer<Object> _createDeserializer(DeserializationConfig config, JavaType type, BeanProperty property) throws JsonMappingException { 
     if (type.isMapLikeType()) {  // (1) 
      return this._factory.createBeanDeserializer(config, this, type, property); 
     } else { 
      return super._createDeserializer(config, type, property); 
     } 
    } 
} 

(1)使用,如果條件滿足您的需求

定製解串器是在ObjectMapper直接登記:

ObjectMapper om = new ObjectMapper(); 
om.setDeserializerProvider(new MyDeserializerProvider()); 

我用傑克遜1.9.11測試了這個。