2012-08-30 218 views
2

這是我的冷杉titme處理類型映射和每次我嘗試將節點映射到具有與Set<Integer>值自定義屬性鍵FooType我的實際類型對象。這裏是我的對象看起來像的Json傑克遜映射通用映射類型問題

public class Foo { 
    private String some; 
    Map<FooTypes,Set<Integer>> foos; 

    public Map<FooTypes, Set<Integer>> getFoos() { 
     return foos; 
    } 
    public void setFoos(Map<FooTypes, Set<Integer>> map) { 
     this.foos = map; 
    } 
    public String getSome() { 
     return some; 
    } 
    public void setSome(String some) { 
     this.some = some; 
    } 
} 

public class FooTypes { 
    private String name; 
    private String id; 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getId() { 
     return id; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 
} 

現在每次我嘗試使用映射器讀取值: -

List <Foo> response = mapper.readValue("/home/foo/foo.json",List.class);

我得到一個錯誤,指出: -

Can not find a (Map) Key deserializer for type [simple type, class cruft.FooTypes]

有人能告訴我如何解決這個問題?謝謝。

JSON輸出: -

{"foos":{"FooTypes [id=1, name=Test Foo]":[1,2,3]},"some":hello},{"foos":{"FooTypes [id=2, name=Another foo]":[5,6,7]}} 

回答

7

由於我們沒有你想要反序列化的Json結構,這有點難以幫助你,但是這裏的問題是Jackson不知道如何反序列化你的類當它被用作地圖鍵。 Jackson的所有信息都是一個簡單的字符串,而你的類沒有提供只用字符串創建它的方法。

還有3的方式來實現這一目標:

  1. 添加一個字符串參數的構造函數,以您的FooType類
  2. 添加一個字符串參數工廠方法(靜態),並與@JsonCreator
  3. 使用其標註定製KeyDeserializer和註釋foos場與@JsonDeserialize(keyUsing=YourDeserializer.class)

IMHO靜態工廠法是更清潔的方式。

+0

我採納了你的建議,並使用更加清潔的靜態工廠方法。它有點不好意思,我不得不substring的(字符串)鍵,所以我可以設置適當的FooTypes值到我的對象,然後從工廠方法返回它。 –

+0

當我嘗試在我的靜態工廠方法中返回mapper.readValue(key,FooTypes.class)時,我得到構造Key類型的異常。所以我去了骯髒的方式和substring的關鍵,得到的價值觀,然後將其設置在我的對象。還有其他方法可以完成嗎?這似乎有點hacky –

+0

你不能在靜態工廠中使用ObjectMapper(請參閱http://stackoverflow.com/questions/12106552/json-weired-key-exception/12112508#12112508)。不,沒有其他方法,這是JSON的限制。你的JSON可能看起來像{「name-id1」:「somefoo」,「name-id2」:someotherfoo「};只要你有一個String形式的FooType的正式表示,應該不會有問題。 –

2

既然你非基本類型的映射鍵(FooTypes),你需要編寫自己的自定義解串器在Jackson wiki描述,因爲傑克遜不能簡單地將字符串值"FooTypes [id=1, name=Test Foo]"(這似乎是FooTypes.toString()的結果)轉換爲FooTypes實例。

在我看來,使用非字符串序列化映射並不是一個好習慣。 JSON表示法不支持除映射鍵字符串之外的任何內容(如指定的here)。我認爲更好的方法是在序列化之前和反序列化之後重新組織數據結構。