2016-09-29 106 views
0

掙扎着看起來像平凡的東西,應該沒有任何問題的工作。我有帶「@class」屬性的JSON,並且在調用時不知道它是類readValue()想將其反序列化到由「@class」引用的類的對象中。我取而代之的是「LinkedHashMap」。平凡的JSON傑克遜多態反序列化

@Test 
public void toJsonAndBack() throws Exception { 
    ObjectMapper mapper = new ObjectMapper(); 
    String json = mapper.writeValueAsString(new Sample("id")); 
    assertTrue(json.contains("@class")); 
    Sample obj = (Sample)mapper.readValue(json, Object.class); 
} 

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS) 
static class Sample { 
    private String id; 

    public Sample() { 
    } 

    public Sample(String id) { 
     this.id = id; 
    } 

    public String getId() { 
     return id; 
    } 
} 

對不起,如果重複,但無法找到完全相同的問題。大多數人有更復雜的情況,其中有基類,這也是註釋,等等。這些案件實際上工作正常。

我使用的是傑克遜2.6.6

+0

不知道我理解你的問題,但反序列化的正確用法就是'Sample obj = mapper.readValue(json,Sample.class);',不投射。 – Mena

+0

@Mena事實上,情況當然更復雜一些,這只是舉例說明所需的行爲。我不能使用類型信息。 – Stas

回答

1

傑克遜將其轉換爲LinkedhashMap,這樣以後,我們就可以使用到轉換給LinkedhashMap其轉換方法引入自定義對象。所以在這裏你需要再增加一個步驟。

E.g:

ObjectMapper mapper = new ObjectMapper(); 
String json = mapper.writeValueAsString(new Sample("id")); 
Object obj = mapper.readValue(json, Object.class); 
Sample sample = mapper.convertValue(obj, Sample.class); 

所以,你可以保持這個OBJ的地方,可它在您方便的轉換成Sample類。

+0

Thx,這是可行的。我可以從地圖讀取「@class」屬性,獲取該類並將其傳遞到convertValue()。我只是希望把所有的管道都放在傑克遜手柄上。 – Stas

0

顯然,加入這一行使得這個測試工作:

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); 

在試樣類註釋的情況下是沒有必要的。