JsonNodeをPOJOに変換する


143

これは、少し変わったように見えるかもしれないが、私は/変換マッピングするための効率的な方法を探していますJsonNodePOJO

モデルの情報の一部を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モデルに適用するだけです

回答:


264

ジャクソン2.4では、次のように変換できます。

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

jsonObjectMapperジャクソンはどこですObjectMapper


古いバージョンのジャクソンでは、

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

18
残念ながら、readValue()のようにtreeToValue(TreeNode n、TypeReference <T> type)バリアントはありません。ジェネリックでより複雑な型を扱う人にとっては悪いニュース:(
Espinosa

13
@Espinosa per jackson- databind #1294、あなたは(残念ながらもっと冗長な)のようなものが必要になるでしょうjsonObjectMapper.readValue(jsonObjectMapper.treeAsTokens(someJsonNode), someTypeReference)
M. Justin

古いバージョンの場合:objectMapper.treeToValue(jsonNode, MyClass.class)
amod

2
このメソッドはStdDeserializerでも使用できますp.codec.treeToValue
galcyurio

@icedtrees jsonObjectMapperは、JsonObjectMapperまたは単なるObjectMapperのインスタンスです
KNDheeraj

8

これでうまくいくはずです:

mapper.readValue(fileReader, MyClass.class);

私はそれをa 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)

次のインスタンスを作成するときに、カスタムデシリアライザーを定義することもできます。httpObjectMapper : //wiki.fasterxml.com/JacksonHowToCustomDeserializers

編集:私は何か他のことを思い出しました。入ってくるオブジェクトが持っているよりも多くのプロパティを持っていPOJOて、あなたが単にこれを設定したい追加を無視したい場合:

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

または、設定するプロパティが見つからないというエラーが発生します。


私はCustomDeserializersを使用します、それは私に多くの頭痛を救うつもりです!また、変更をほとんど加えずにバージョン管理戦略を適用することもできます。ありがとう!
アレクサンドル

5
構文は次のとおりです。com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
llambda 2014

良い点@llambda!バージョン1.7.9からObjectMapperに触れていませんが、いくつかのバージョンでは私の回答が古くなっているようです。使用しているジャクソンのバージョンを必ず確認してください。
Eric Barr

@EricBarr、私はジャクソンv1.9.11を使用しており、あなたの答えの構文はそのバージョンの正しいものです。おそらく、彼らは物事を変更しようとし、新しいバージョンで再び元に戻しました
Ivaylo Slavov 2014年

5

org.codehaus.jacksonを使用している場合、これは1.6以降で可能です。あなたがPOJOにJsonNodeを変換することができます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で欠落しているようです
Kevin Wittek

1
バージョン2のソリューションについては、以下のicedtreesの回答を参照してください
TimBütheMar


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よりも多くのプロパティがあり、Jackson 2.4の追加機能を無視したい場合は、次のようにObjectMapperを構成できます。この構文は、古いJacksonバージョンとは異なります。(間違った構文を使用すると、黙って何も行われません。)

mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.