はじめに
この記事は、JavaでREST APIや設定ファイルを扱っていて「JacksonのJsonNodeに新しいプロパティを追加・上書きしたいけど、やり方がいまいち分からない」という中級者の方を対象にしています。
記事を読むことで、ObjectNodeとArrayNodeの違いを理解し、put()/set()/add()メソッドを使ってJsonNodeに値をセットできるようになります。実装でよくハマる「不変のJsonNodeに追加しようとして例外が出る」問題も、原因と回避策をあわせて解説します。
前提知識
- Java 11以降の基本的な文法
- JacksonでJSONを読み込み、
JsonNodeとして取得できること - Maven/Gradleで
jackson-databindが依存に含まれていること
JacksonでJsonNodeを更新する必要性
Jacksonは、JSONをツリー型のJsonNodeとして扱えるため、フィールド名が動的に変わるようなケースでも便利です。ただし、読み取り専用のJsonNodeをそのまま変更しようとするとUnsupportedOperationExceptionが発生します。
そこで、読み書き可能なObjectNode/ArrayNodeに変換してから値をセットする手法を押さえておくことが、堅牢なJSON加工の第一歩になります。
ステップバイステップ:JsonNodeに値をセットする
ステップ1:ObjectNodeにプロパティを追加・上書きする
まず、JSON文字列を読み込み、新規プロパティを追加してみます。
JavaObjectMapper mapper = new ObjectMapper(); ObjectNode root = (ObjectNode) mapper.readTree(""" {"name":"taro","age":20} """); root.put("email", "taro@example.com"); // 文字列追加 root.put("age", 25); // 数値上書き root.set("address", mapper.createObjectNode() // オブジェクト追加 .put("zip", "150-0001") .put("city", "Shibuya")); System.out.println(root.toPrettyString());
出力例
Json{ "name" : "taro", "age" : 25, "email" : "taro@example.com", "address" : { "zip" : "150-0001", "city" : "Shibuya" } }
ステップ2:ArrayNodeに要素を追加する
次に、配列を扱います。add()で末尾に追加、set(index, node)で上書きが可能です。
JavaArrayNode hobbies = mapper.createArrayNode() .add("soccer") .add("music"); hobbies.add("programming"); // 末尾追加 hobbies.set(1, mapper.valueToNode("guitar")); // 1番目を上書き root.set("hobbies", hobbies);
配列の要素もJsonNodeでラップするため、プリミティブ型はvalueToNode()で変換すると便利です。
よくあるエラー:UnsupportedOperationException
読み取り専用のJsonNodeを直接更新しようとすると、以下のような例外が出ます。
Exception in thread "main" java.lang.UnsupportedOperationException:
Not an ObjectNode
これは、JsonNodeが不変であるためです。必ずObjectNode/ArrayNodeにキャストするか、createObjectNode()/createArrayNode()で新規作成してから操作してください。
解決策:不変を回避する3パターン
-
読み取り専用ノードをコピーする
ObjectNode editable = root.deepCopy(); -
新規作成してから差し替える
ObjectNode editable = mapper.createObjectNode(); -
読み込み時点から
ObjectNodeとして受ける
ObjectNode root = mapper.readValue(json, ObjectNode.class);
どのパターンでも、操作後にtoPrettyString()でログ出力するとデバッグが捗きます。
まとめ
本記事では、JacksonのJsonNodeに値をセットする方法を解説しました。
ObjectNodeならput()/set()でプロパティ追加・上書きArrayNodeならadd()/set(index,node)で要素操作- 読み取り専用ノードはコピーor新規作成してから変更
この知識があれば、設定ファイルの差分更新や、REST APIレスポンスの動的な書き換えが安全に行えます。次回は、JsonNodeをJavaオブジェクトに戻す(デシリアライズ)テクニックについて深掘りします。
参考資料
- Jackson公式ドキュメント – Tree Model
- Baeldung – Jackson ObjectNode and ArrayNode
- 伊藤直也・須藤 賢明『Java基礎 完全ランニング』(技術評論社)
