2013-10-31 62 views
78

這看起來可能有點不尋常,但我正在尋找一種有效的方法來將JsonNode轉換爲POJO將JsonNode轉換爲POJO

我將一些模型的信息存儲在json文件中,我必須支持我的模型的幾個版本。

我所做的是在JsonNode的內存中加載json文件,應用幾個版本控制策略使其與我的模型的最新版本匹配。

ObjectMapper mapper = new ObjectMapper(); 
    BufferedReader fileReader = new BufferedReader(new FileReader(projPath)); 

    JsonNode rootNode = mapper.readTree(fileReader); 

    //Upgrade our file in memory 
    applyVersioningStrategy(rootNode); 

    ProjectModel project = mapJsonNodeToProject(rootNode); 

,除非有一個更快的方式做到這一點,我最終可能會簡單地手動應用JsonNodes到我的模型

+0

給定的票數獲得,絕對不在少數。 – DPM

回答

157

在傑克遜2.4,您可以按如下轉換:

MyClass newJsonNode = jsonObjectMapper.treeToValue(someJsonNode, MyClass.class); 

其中jsonObjectMapper是傑克遜ObjectMapper


在舊版本的傑克遜,這將是

MyClass newJsonNode = jsonObjectMapper.readValue(someJsonNode, MyClass.class); 
+13

不幸的是,沒有treeToValue(TreeNode n,TypeReference 類型)類似於readValue()。任何人處理更復雜類型的泛型:( – Espinosa

+8

@Espinosa Per [jackson-databind#1294](https://github.com/FasterXML/jackson-databind/issues/1294)的壞消息,你會想要類似(不幸的是更詳細)'jsonObjectMapper.readValue(jsonObjectMapper.treeAsTokens(someJsonNode),someTypeReference)' –

+0

對於舊版本使用:'objectMapper.treeToValue(jsonNode,MyClass.class)' – amod

8

這應該做的伎倆:

​​

我說應該是因爲我使用的是String,而不是BufferedReader,但它仍然可以工作。

這裏是我的代碼:

String inputString = // I grab my string here 
MySessionClass sessionObject; 
try { 
    ObjectMapper objectMapper = new ObjectMapper(); 
    sessionObject = objectMapper.readValue(inputString, MySessionClass.class); 

下面是該呼叫的官方文檔:http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)

您也可以自定義一個解串器,當你實例化ObjectMapperhttp://wiki.fasterxml.com/JacksonHowToCustomDeserializers

編輯: 我只記得別的東西。如果你進來對象有更多的屬性比POJO具有隻是想和你忽略的額外你要設置這樣的:

objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

否則你會得到一個錯誤,它無法找到該物業設置成。

+0

我將使用CustomDeserializers,它會爲我節省很多頭痛! 我也可以在那裏適用我的版本控制策略,只需很少的修改。謝謝! – Alexandre

+2

現在的語法是: com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); – llambda

+0

好點@llambda!自1.7.9版本以來我沒有碰過ObjectMapper,看起來我的答案已經過時了幾個版本。絕對檢查你使用的是什麼版本的傑克遜。 –

3
String jsonInput = "{ \"hi\": \"Assume this is the JSON\"} "; 
com.fasterxml.jackson.databind.ObjectMapper mapper = 
    new com.fasterxml.jackson.databind.ObjectMapper(); 
MyClass myObject = objectMapper.readValue(jsonInput, MyClass.class); 

如果你的JSON輸入具有更多的屬性比你的POJO有隻想和你忽略傑克遜2.4臨時演員,你可以按照以下方式配置ObjectMapper。 此語法與舊版Jackson不同。如果您使用org.codehaus.jackson(如果你使用了錯誤的語法,它會悄悄地做任何事。)

mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES); 
4

,這因爲1.6是不可能的。您可以將JsonNode轉換成POJO與ObjectMapper#readValuehttp://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(org.codehaus.jackson.JsonNode,java.lang.Class中)


    ObjectMapper mapper = new ObjectMapper(); 
    JsonParser jsonParser = mapper.getJsonFactory().createJsonParser("{\"foo\":\"bar\"}"); 
    JsonNode tree = jsonParser.readValueAsTree(); 
    // Do stuff to the tree 
    mapper.readValue(tree, Foo.class); 
+5

這種方法似乎在2.4.4中丟失 –

+1

請參見下面的icedtrees'[answer](http://stackoverflow.com/a/28714523/60518),for版本2解決方案 –

+0

該文檔現在位於https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html –