(2020/11/27編集)読みづらいので文章を修正
プロフィール
Spring BootでJava初めて半年
-> Kotlinに引っ越して半月
Kotlin公式JSONとは
KotlinでJSONを文字列に変換するデフォルト実装機能。
build.gradle.ktには
plugins {
kotlin("jvm") version "1.4.10"
kotlin("plugin.serialization") version "1.4.10"
}
と
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC")
}
を追記する。
クラス -> JSON文字列
そもそもJSONとは、JavaScript Object Notation、
すなわち名前(key)と値(value)の組み合わせがいっぱい入った構造を、JavaScriptのObjectのような書き方で表現した文字列。
{
"name": "hoge",
"age": 1,
"friends": [
{
"name": "fuga",
"like": true
},
{
"name": "piyo",
"like": false
}
]
}
JavaScriptならJavaScriptのObjectをJSONに変換するが、
Kotlinでは、データクラスをJSONに変換する。
例
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@Serializable
class Person(
val name: String,
val age: Int,
val firends: List<Friend>
)
@Serializable
class Friend(
val name: String,
val like: Boolean,
)
fun main() {
val hoge = Person(
"hoge",
1,
listOf(
Friend("fuga",true),
Friend("piyo",false)))
println(Json.encodeToString(hoge))
}
出力結果
{"name":"hoge","age":1,"firends":[{"name":"fuga","like":true},{"name":"piyo","like":false}]}
要点は、
- JSON化するクラスには、@Serializableをつける
- クラスのプロパティ名(nameなど)が、変換後にJSONのkeyとなる
- Listも使える
- クラスの入れ子もできる
応用 (特定のプロパティをJSONに変換しない)
デフォルト
デフォルトでは、全てのプロパティがJSONに変換されてしまうので、ちょっと困る。
先の例だと、friendsがnullでも、そのままJSONに変換される。
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
@Serializable
class Person(
val name: String,
val age: Int,
val firends: List<Friend>? = null // 変更箇所
)
@Serializable
class Friend(
val name: String,
val like: Boolean,
)
fun main() {
val hoge = Person("hoge", 1) // 変更箇所
println(Json.encodeToString(hoge))
}
出力結果
{"name":"hoge","age":1,"firends":null}
特定のプロパティをJSONから消す
// クラスとインポートは同じ
val format = Json {encodeDefaults = false}
fun main() {
val hoge = Person("hoge", 1)
println(format.encodeToString(hoge)) // Jsonがformatに変わっている
}
出力結果
{"name":"hoge","age":1}
最初の行の encodeDefaults = false は、デフォルト引数と同じ値のプロパティ(今回は friends = null )はJSONに変換しない、という意味。
明示的に代入した場合
デフォルト引数と同じ値のプロパティは全て弾かれるので、
// クラスとインポートは同じ
val format = Json {encodeDefaults = false}
fun main() {
val hoge = Person("hoge", 1, null) // nullを明示的に代入
println(format.encodeToString(hoge))
}
出力結果
{"name":"hoge","age":1}
明示的にデフォルト引数と同じ値を代入しても弾かれる
さらに学びたい人へ
英語のガイドがあります