2013-10-31 8 views
78

これはちょっと変わったようですが、JsonNodePOJOに変換/マップする効率的な方法を探しています。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

:あなたはObjectMapper#readValueでPOJOにJsonNodeに変換することができます

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

ジャクソン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ではなく、まだ動作しています。ここで

は私のコードです:あなたはObjectMapperをインスタンス化するときには、また、カスタムデシリアライザを定義することができますhttp://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)

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

ここでは、その呼び出しのための公式ドキュメントです http://wiki.fasterxml.com/JacksonHowToCustomDeserializers

編集: 私はちょうど何かを覚えていた。

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

それとも、それが財産を見つけることができないというエラーが発生します:に来て、あなたのオブジェクトがPOJOが持っている、あなたはちょうどあなたがこれを設定することをお勧めしますエキストラを無視するよりも多くの特性を持っている場合設定する。あなたのPOJOが持っているとあなただけのジャクソン2.4でエキストラを無視するよりも、自分の中にJSON入力は複数のプロパティを持っている場合は、次のよう

+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

良い点@λ!バージョン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); 

は、あなたのObjectMapperを設定することができます。 この構文は、以前のJacksonバージョンとは異なります。(間違った構文を使用している場合、それは黙って何もしません。)

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

あなたがorg.codehaus.jacksonを使用している場合、これは1.6以降可能となっています。次のように変換することができ、ジャクソン2.4ではhttp://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)を参照してください。バージョン2のソリューション –

+0

ドキュメントは現在https://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/ObjectMapper.html –

関連する問題