2015-11-02 26 views
1

我遇到以下問題:有一個REST API返回想要映射到List的JSON字符串。 MyObject有幾個字段,其中一些是int/double。讓我們考慮一下API可能會返回字符串而不是ints /雙精度對於其中一些MyObject的字段,其餘都沒關係。jackson:在反序列化列表時捕獲單個項的異常

現在我希望映射器仍然映射此列表,同時拋出有問題的MyObjects。但是,撥打

objectMapper.readValue(jsonString, TypeFactory.defaultInstance().constructCollectionType(List.class, MyObject.class)); 

將成功,如果所有MyObjects都沒問題或在面對第一個問題時完全失敗。

我希望能找到一個地方,它映射器遍歷JSON-MyObjects列表並將它們逐一映射到Java-MyObjects。這樣我就可以覆蓋該行爲,並可能用try-catch塊將其包圍,並捕獲映射單個MyObject時發生的任何異常。到目前爲止沒有運氣,但也許我只是失明。

任何想法如何與傑克遜完成這一點非常感謝。

回答

0

我能夠通過使用傑克遜的自定義解串器來實現這一目標:

這裏是我的MyObject對象類別。它有一個註釋,它與一個自定義解串器相關聯:

@JsonDeserialize(using = MyObjectDeserializer.class) 
public class MyObject 
{ 
    public int num; 
    public String str; 

    @Override 
    public String toString() 
    { 
     return "{" + num + "," + str + "}"; 
    } 
} 

這裏是自定義解串器。它檢查「NUM」屬性的類型是int類型的:

public class MyObjectDeserializer extends JsonDeserializer<MyObject> 
{ 
    // read current MyObject json node 
    JsonNode myObjectNode = jp.getCodec().readTree(jp);// this will read 
    // read "num" property into JsonNode and check what subclass was created 
    JsonNode numNode = myObjectNode.get("num"); 
    if (numNode instanceof IntNode) { // test if value of num is int indeed 
     MyObject o = new MyObject(); 
     o.num = ((IntNode)numNode).intValue(); // read int value 
     o.str = ((TextNode)myObjectNode.get("str")).asText(); // this is how to read string typed property 
     return o; 
    } else { 
     return null; // or any default/error value 
    } 
} 

現在假設以下的輸入,注意第二對象的字符串輸入「NUM」屬性:

[{"num":1,"str":"n1"}, {"num":"s","str":"n2"}, {"num":3,"str":"n3"}] 

而不自定義的反序列化器,你會得到一個異常。並用它得到輸出:

[{1,n1}, null, {3,n3}] 
+0

工作就像一個魅力,非常感謝你! – stormpanda