2012-10-24 24 views
0

我同時使用enableDefaultTyping並提供一個通用的TypeRefernce時遇到了反序列化問題。傑克遜似乎無法確定哪種類型的信息更重要。這測試用例demonstarting問題:傑克遜泛型類型引用+ enableDefaultTyping問題

@Test 
public void roundTripTest() throws JsonGenerationException, 
     JsonMappingException, IOException { 

    // 0 Value Test 
    Integer[] integers = new Integer[] {}; 
    Wrap<Integer[]> beforeResult = new Wrap<Integer[]>(integers); 

    File file = new File("/tmp/jsonTest"); 
    mapper.writeValue(file, beforeResult); 

    TypeReference<Wrap<Integer[]>> typeRef = new TypeReference<JacksonMapperTest.Wrap<Integer[]>>() { 
    }; 

    Wrap<Integer[]> afterResult = mapper.readValue(file, typeRef); 

    assertNotNull(afterResult); 

} 


public static class Wrap<T> { 

    private T wrapped; 

    public Wrap() { 
    } 

    public Wrap(T wrapped) { 
     this.wrapped = wrapped; 
    } 

    public T getWrapped() { 
     return wrapped; 
    } 

    public void setWrapped(T wrapped) { 
     this.wrapped = wrapped; 
    } 
} 

其中映射是:

mapper = new ObjectMapper(); 
mapper.enableDefaultTyping(); 

和例外是:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class JacksonMapperTest$Wrap<[Ljava.lang.Integer;>]: can not instantiate from JSON object (need to add/enable type information?) 

很奇怪,不是嗎?通過使用beforeResult.getClass而不是TypeRefernce,可以忽略該問題,但它仍然不是首選的行爲。

我錯過任何種類的選擇爲了解決這個問題?

我用傑克遜1.9.3

[編輯] 使用地圖不是數組作爲包裝的對象按預期工作!

回答

2

這似乎是傑克遜的一個錯誤......但是它的作者可能更有能力判斷它是否是一個錯誤......如果你可以自由地從傑克遜改變看一下genson http://code.google.com/p/genson/

Gensons相當於enableDefaultTyping是setUseRuntimeTypeForSerialization(不完全一樣,但在大多數情況下是非常相似)。它在序列化期間使用運行時類型。這裏有一個例子:

Genson genson = new Genson.Builder().setUseRuntimeTypeForSerialization(true).create(); 
String json = genson.serialize(beforeResult); 
System.out.println(json); 
GenericType<Wrap<Integer[]>> type = new GenericType<Wrap<Integer[]>>() {}; 
Wrap<Integer[]> afterResult = genson.deserialize(json, type); 

編輯 如果您需要能夠反序列化到polymoprhic或未知類型的genson使用Genson.Builder的setWithClassMetadata(真)。這個特性實際上只用於json對象(不管它是否是抽象類)。

0

我不知道確切的根源100%,但我懷疑這是與Java類型擦除做的,從通過泛型感知信息,並與默認的類型信息混合的IT問題。類型信息實際上僅基於非泛型類型;但是,它適用於特定種類的泛型類型(地圖,集合)。

但在這種情況下,你有自定義泛型類型;我認爲這正是傑克遜無法爲動態類型的目的指明泛型屬性的原因。

通常的解決方法是嘗試子類如果可能的話;但幸運的是,您可以找到更好的解決方法。