2012-06-28 164 views
12

非字符串映射鍵我有機管局地圖,看起來像這樣:反序列化與傑克遜

public class VerbResult { 
    @JsonProperty("similarVerbs") 
    private Map<Verb, List<Verb>> similarVerbs; 
} 

我動詞類看起來是這樣的:

public class Verb extends Word { 
    @JsonCreator 
    public Verb(@JsonProperty("start") int start, @JsonProperty("length") int length, 
      @JsonProperty("type") String type, @JsonProperty("value") VerbInfo value) { 
     super(length, length, type, value); 
    } 
    //... 
} 

我想序列化和反序列化的情況下,我VerbResult類,但當我做我得到這個錯誤:Can not find a (Map) Key deserializer for type [simple type, class my.package.Verb]

我在網上讀到,你需要告訴傑克遜如何反序列化映射鍵,但我沒有找到任何信息解釋如何去做這件事。動詞類需要在地圖之外進行序列化和反序列化,因此任何解決方案都應該保留此功能。

謝謝你的幫助。

+0

作品有你讀http://stackoverflow.com/questions/6371092/can-not-find-a-map-key-deserializer-for-type -simple-type-class-com-comcast-i?他的情況看起來與你的一見鍾情。 – fvu

+0

是的,我已經閱讀過,但實際上我沒有找到答案。我怎樣才能使用模塊來解決這個問題? – Max

回答

3

建立在answer given here上,建議使用解串器實現模塊我參考the Jackson Module documentationJodaTime Module是一個容易理解的包含序列化器和解串器的模塊的完整示例。

請注意,模塊功能是在傑克遜版本1.7中引入的,因此您可能需要升級。

所以一步一步:

  1. 創建基於喬達例如包含相關類的(反)序列化模塊
  2. 註冊mapper.registerModule(module);

,你會認爲模塊全部設置

+0

太棒了!非常感謝。 – Max

+2

還有一個附加說明:您需要添加的是「鍵(解)序列化程序」:由於Map鍵具有其他限制,常規(de)序列化程序無法按原樣使用。但是可以肯定地從模塊完成註冊。 – StaxMan

+3

@Max您是否可以提供如何實現解串器的代碼?我希望看到,如果可能=) – Ted

8

如上所述,訣竅是你需要一個解串器(this也抓到我了)。在我的情況下,在我的類上配置了一個非String映射鍵,但它並不在我解析的JSON中,所以一個非常簡單的解決方案對我來說很簡單(只需在關鍵解串器中返回null)。

public class ExampleClassKeyDeserializer extends KeyDeserializer 
{ 
    @Override 
    public Object deserializeKey(final String key, 
            final DeserializationContext ctxt) 
     throws IOException, JsonProcessingException 
    { 
     return null; 
    } 
} 

public class ExampleJacksonModule extends SimpleModule 
{ 
    public ExampleJacksonModule() 
    { 
     addKeyDeserializer(
      ExampleClass.class, 
      new ExampleClassKeyDeserializer()); 
    } 
} 

final ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new ExampleJacksonModule()); 
13

經過一天的搜索,我發現了一個更簡單的方法,它基於this question。解決方案是將@JsonDeserialize(keyUsing = YourCustomDeserializer.class)註釋添加到地圖。然後通過擴展KeyDeserializer並覆蓋deserializeKey方法來實現您的自定義解串器。該方法將使用字符串鍵調用,您可以使用該字符串構建真實對象,甚至可以從數據庫中獲取現有對象。

所以先在地圖聲明:

@JsonDeserialize(keyUsing = MyCustomDeserializer.class) 
private Map<Verb, List<Verb>> similarVerbs; 

然後創建將與該字符串鍵被稱爲解串器。

public class MyCustomDeserializer extends KeyDeserializer { 
    @Override 
    public MyMapKey deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     //Use the string key here to return a real map key object 
     return mapKey; 
    } 
} 

與新澤西州和傑克遜2.X

+0

我一直在試圖把註釋放在關鍵類本身(在你的情況下是'Verb'),而不是在地圖聲明上。你救了我更多的頭撓,謝謝! – snappieT