29
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kotlin Serializationの使い方を詳しく調べてみた

Last updated at Posted at 2019-01-20

はじめに

TechBoosterの書籍でKotlin Serializationが少し触れられていたのですが、現在開発中のプロジェクトで利用できそうだったため、もう少し詳しく調べてみることにしました。

Kotlin Serializationとは

  • シリアライザ・デシリアライザである(コード自動生成用のコンパイラプラグインとシリアライズ用のランタイムライブラリの構成)
  • JSON, CBOR, Protobufの3つのフォーマットをサポートし、さらに有志が作成したアドオンを使えばHOCON, YAMLも使える
  • Kotlin/JVM, Kotlin/JS, Kotlin/Nativeプラットフォームをサポート
  • リフレクションを使用しない ー> リフレクション使用しない分速い! 
    (MoshiやGsonなどのパーサーはJsonキーとプロパティを紐付ける際などにリフレクションを使用している)

インストール手順

  • 今回はAndroidを前提にしているのでその他のプラットフォーム用の設定は公式参照のこと
build.gradle

buildscript {
    ext.kotlin_version = '1.3.20'
    repositories { jcenter() }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}
app/build.gradle
apply plugin: 'kotlin'
apply plugin: 'kotlinx-serialization'

// 略

repositories {
    jcenter()
    // artifacts are published to this repository
    maven { url "https://kotlin.bintray.com/kotlinx" }
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.10.0"
}

使い方

import kotlinx.serialization.*
import kotlinx.serialization.json.Json

@Serializable
data class Data(val a: Int, @Optional val b: String = "42")

fun main(args: Array<String>) {
    // Serializableアノテーションを付けた場合、オブジェクトを渡すだけでOK
    val jsonData = Json.stringify(Data(42))
    // コレクション等も拡張関数serializerを使うことで利用可能
    val jsonList = Json.stringify(Data.serializer().list, listOf(Data(42)))
    println(jsonData) // {"a": 42, "b": "42"}
    println(jsonList) // [{"a": 42, "b": "42"}]

    // 文字列をパースするときも簡単!
    val obj = Json.parse<Data>("""{"a":42}""")
    println(obj) // Data(a=42, b="42")

    // unquotedはフォーマットからダブルクォーテーションを外す
    assertEquals("{a:1, b:42}", Json.unquoted.stringify(Data(1)))
    assertEquals(Data(1), Json.unquoted.parse<Data>("{a:1, b:42}"))
}

引用元: https://github.com/Kotlin/kotlinx.serialization#quick-example

アノテーションについて

アノテーション 概要
Serializable シリアライズしたいカスタムクラスに付けることでシリアライゼーションできる
Optional 必須ではないパラメータに付ける。付けない場合はエラーになる
SerialName Jsonキー名が異なる場合に付ける
Transient Jsonで扱わないプロパティを定義したい場合に使用する。Jsonにこのプロパティが存在していた場合エラーになる
SerialInfo アノテーションクラスを定義するためのアノテーション。
プロパティにタグなどの情報をもたせることが出来て、エンコーダー内でタグをもとに条件分岐などに利用できる。
Protobufなどで利用する

アノテーションの使い方


// シリアライズしたいクラスに付与
@Serializable
data class Data(
   val a: Int,
   // 必須パラメーターではない場合に付ける
   @Optional
   val b: String = 42,
   // jsonキー名がcでプロパティ名とことなる場合
   @SerialName("c")
   val d: String
)

カスタムシリアライザ

  • シリアライザを自作することも可能。このサンプルは日付を扱う例
@Serializer(forClass = Date::class)
object DateSerializer: KSerializer<Date> {
    private val df: DateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS")

    override val descriptor: SerialDescriptor =
        StringDescriptor.withName("WithCustomDefault")

    override fun serialize(output: Encoder, obj: Date) {
        output.encode(df.format(obj))
    }

    override fun deserialize(input: Decoder): Date {
        return df.parse(input.decode())
    }
}

引用元: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/custom_serializers.md#external-serializers-for-library-classes

終わりに

いかがでしたでしょうか?皆さんもKotlin Serializationを使って快適なシリアライゼーション生活を。

29
24
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
29
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?