JSONの特定の値に応じてパースする型を変えたい
JSONのtypeというパラメータによって、使うフィールドが異なる場合にパッと思いつくやり方は以下かなと思います。
data class User(
// ユーザーのタイプを表す 'free' or 'payed'
val type: String,
// どちらの型でも共通
val name: String,
// freeの場合のみ存在する
val trialEndAt: Date,
// payedの場合のみ存在する
val purchasedAt: Date,
)
{
"users": [
{
"type": "free",
"name": "John",
"trialEndAt": '2022-02-02T19:00:00+09:00'
},
{
"type": "payed",
"name": "Alice",
"purchasedAt": '2022-01-22T19:00:00+09:00'
}
]
}
@JsonTypeInfo
、@JsonSubTypes
を使って型を振り分ける
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") // “type” というJSONのキーで型を判別する
@JsonSubTypes( // “type”の値に応じてどの型にパースするか
value = [
JsonSubTypes.Type(value = User.Free::class, name = "free"),
JsonSubTypes.Type(value = User.Payed::class, name = "payed"),
]
)
sealed class User(val name: String) { // type はフィールドには入れない
data class Free(val trialEndAt: Date) : User()
data class Payed(val purchasedAt: Date) : User()
}
普段は継承をあまり使いたくないが、 sealed class
でスコープを限定することで使いやすくした。
継承にする必要はなく別クラスに定義しても問題ないはず。
参考
Kotlin with Jackson: Deserializing Kotlin Sealed Classes | by Sergii Prodan | Medium JsonDeserializerを使って空の時に型が配列になるプロパティに対応する - Qiita Jacksonで独自のJSONシリアライズをする | GROUP DEV BLOG | TECHNO DIGITAL Jackson使い方メモ - Qiita Parse Snake case JSON in Spring Boot | by Bhanu Chaddha | Medium 備忘録的なblog: Jacksonでsnake caseのキーをlower camel caseのプロパティーにデシリアライズする Jackson overcoming underscores in favor of camel-case