2011-04-18 125 views
8

從JSON使用Jackson庫進行反序列化時,以自定義方式實例化bean(而不是通過調用默認構造函數)的最佳和最簡單的方法是什麼?我發現我可以實現的接口有JsonDeserializer,但我不太確定如何將它們連接到ObjectMapper如何用Jackson自定義方式實例化bean?

UPDATE#1:我想我的問題需要更多的細節。默認情況下,Jackson的反序列化器使用默認的構造函數來創建bean。我希望能夠通過調用外部工廠來實現bean的實例化。所以我需要的只是一個需要實例化的bean的類。工廠將返回可以提供給傑克遜的物業人口的實例等等。

請注意,我並不擔心創建簡單/標量值(如字符串或數字),只有這些bean位於我感興趣的區域。

回答

0

你把解串器的Java對象,你想要得到的JSON映射到:

@JsonDeserialize(using = PropertyValueDeserializer.class) 
public class PROPERTY_VALUE implements Serializable{ 

然後在解串器,你可以如這樣做:

@Override 
public PROPERTY_VALUE deserialize(JsonParser jsonParser, 
        DeserializationContext deserializationContext) 
      throws IOException, JsonProcessingException { 

    String tmp = jsonParser.getText(); // { 
    jsonParser.nextToken(); 
    String key = jsonParser.getText(); 
    jsonParser.nextToken(); 
    String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    PROPERTY_VALUE pv = new PROPERTY_VALUE(key,value); 
    return pv; 
} 

如果你不想使用註釋,你需要通過映射器DeserializerProvider,可以提供給定類型的正確解串器。

mapper.setDeserializerProvider(myDeserializerProvider); 

對於構造 - 當然,你可以通過調用解串器內的工廠產生的目標等級:

String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    MyObject pv = MyObjectFactory.get(key); 
    pv.setValue(value); 
    return pv; 
} 

但後來我可能誤解了您的更新

+0

謝謝Heiko。傑克遜默認使用bean的默認構造函數來創建實例。我想要做的是通過使用外部工廠實際創建bean。我會稍後更新一些細節。 – 2011-04-18 10:08:00

+0

如何在不使用註釋的情況下做到這一點? – 2011-04-18 10:13:30

+1

通過使用混合註釋,它不需要直接添加到類本身,而是添加到其他「混合」類。這使得使用第三方庫的註解方法成爲可能。 – StaxMan 2011-04-18 22:51:09

8

一些事情,可能會幫助...

首先,您可以使用@JsonCreator來定義要使用的替代構造函數(所有參數都必須使用@JsonProperty進行註釋,因爲字節碼有沒有名字),或者一個靜態工廠。它仍然是值類的一部分,但可以幫助支持不可變對象。其次,如果你想要真正的自定義反序列化過程,你可以看看http://wiki.fasterxml.com/JacksonHowToCustomDeserializers,它解釋瞭如何註冊自定義反序列化器。

傑克遜目前錯過的一件事是支持構建器樣式的對象;有一項增加支持的功能請求(並且計劃是在開發者有時間之後在未來添加支持)。

相關問題