LoginSignup
0
0

More than 1 year has passed since last update.

【Jackson】JSONから特定プロパティだけデシリアライズする

Posted at

やりたいこと

以下のようなJSONから、valueプロパティだけを、型を付けてデシリアライズします。

{
    "value": "10", // このプロパティは有ったりなかったりする

    /* 他にも沢山のフィールド */

}

やり方

以下のような読み出し関数を作ることでできます。
サンプルコードはKotlinですが、Javaでも問題なく動くと思います。

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper

val mapper: ObjectMapper = jacksonObjectMapper()

/**
 * @param json 読み出し対象JSON
 * @param targetPropertyName 読み出し対象プロパティ名
 * @param dst デシリアライズ先クラス
 */
fun <T> readProperty(json: JsonNode, targetPropertyName: String, dst: Class<T>): T? {
    // プロパティの読み出し(getの場合無ければnullが返ってくる)
    val readedNode: JsonNode? = json.get(targetPropertyName)

    // プロパティを読み出せた場合、dstに指定した型へデシリアライズする
    return readedNode?.let { mapper.treeToValue(it, dst) }
}

使い方は以下のとおりです。
サンプルコードでは、valueプロパティを文字列や整数として読み出せることと、値がnullのプロパティも問題なく読み出せることを示しています。

val rawJson = """
    {
        "value": "10",
        "hoge": null,
        "fuga": "aaa",
        "piyo": 0
    }
""".trimIndent()

val json: JsonNode = mapper.readTree(rawJson)

// 文字列として読み出し
val asString: String = readProperty(json, "value", String::class.java)!! // "10"
// 整数として読み出し
val asInt: Int = readProperty(json, "value", Int::class.java)!! // 10

// nullも読み出せる
val asNull: Int? = readProperty(json, "hoge", Int::class.java)

補足1: 再帰的にプロパティを見つけたい場合

ネストしたJSONで、深い階層に有るプロパティも処理対象としたい場合、findValueでの読み出しが使えます。

- val readedNode: JsonNode? = json.get(targetPropertyName)
+ val readedNode: JsonNode? = json.findValue(targetPropertyName)

補足2: カスタムデシリアライザについて

サンプルコード内で利用しているObjectMapperにカスタムデシリアライザを登録することで、treeToValueの処理時にデシリアライザを適用することが可能です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0