- kotlin serialization User Guide
- 1, Add serialization dependency
- 2, Kotlin serialization Guide
- 1. Serialization operation
- 1. Fields that can be serialized
- 2. Default action
- 3. Mandatory security type
- 4. Sequence field name
- 2. Deserialization operation
- 1. Optional properties
- 2. Required properties
- 3. JSON property settings
- Hot Keywords
- Kotlin JSON serialization crash course
- Set up
- Usage
- Prepare your data classes
- Serialize/Deserialize
- Ignore and optional fields
- Сериализация Kotlin с помощью Kotlinx.Serialization
- Пример Grundle для мультиплатформенного использования
- Для Android
- Сериализация
- @Transient и @Optional
- Пример для Android с использованием Retrofit
- Список репозиториев
kotlin serialization User Guide
Kotlin serialization is a plug-in officially provided by kotlin, which can serialize and deserialize kotlin objects. The supported serialization formats include JSON, Protobuf, CBOR, Hocon and Properties
serialization is easy to use:
//serialize val data = Project("kotlinx.serialization", "Kotlin") val json = Json.encodeToString(data) //Deserialization val obj = Json.decodeFromString(json)
1, Add serialization dependency
In module Add in build.gradle
In project Add in build.gradle
2, Kotlin serialization Guide
1. Serialization operation
@Serializable class Project(val name: String, val language: String) fun main()
1. Fields that can be serialized
Only properties of classes with supported fields will be serialized, so properties with getters / setters and without supported fields and delegate properties will not be serialized, as shown in the following example.
@Serializable class Project( // name has supported field properties and can be serialized var name: String ) < var stars: Int = 0 // With supported field properties, it can be serialized val path: String //Without field, it will not be serialized get() = "kotlin/$name" var id by ::name //Proxy properties, not serialized >fun main() < val data = Project("kotlinx.serialization").apply < stars = 9000 >println(Json.encodeToString(data)) > //print:
2. Default action
By default, the default value does not participate in encoding:
@Serializable data class Project(val name: String, val language: String = «Kotlin») fun main() < val data = Project("kotlinx.serialization") println(Json.encodeToString(data)) >print:
If you need the default value to participate in serialization, you can set the encodeDefaults property:
@Serializable class Project( val name: String, val language: String = «Kotlin», val website: String? = null) fun main() < val data = Project("kotlinx.serialization") println(Json < encodeDefaults = true >.encodeToString(data)) > print:
Explicit nulls can be set to false if you do not want null to participate in serialization
3. Mandatory security type
serialization implements the type safety of Kotlin language. If there is null in json and the corresponding attribute is not marked as nullable, an exception will be reported
@Serializable data class Project(val name: String, val language: String = "Kotlin") fun main() < val data = Json.decodeFromString(""" """) println(data) >
Error: Unexpected JSON token at offset 52: Expected string literal but ‘null’ literal was found
Use ‘coerceInputValues = true’ in ‘Json <>` builder to coerce nulls to default values.
If you want to use the default value when json is null, set coerceInputValues = true
@Serializable data class Project(val name: String, val language: String = "Kotlin") fun main() < val data = Json < coerceInputValues = true >.decodeFromString(""" """) println(data) > print: Project(name=kotlinx.serialization, language=Kotlin)
4. Sequence field name
By default, the attribute names used in the encoded representation (JSON in our example) are the same as their names in the source code. The name used for serialization is called the sequence name and can be changed using the @ SerialName annotation
@Serializable class Project(val name: String, @SerialName(«lang») val language: String) fun main() < val data = Project("kotlinx.serialization", "Kotlin") println(Json.encodeToString(data)) >print:
2. Deserialization operation
@Serializable class Project(val name: String, val language: String) fun main()
1. Optional properties
An object can be deserialized only if all the properties of the object exist in the sequence. For example:
@Serializable data class Project(val name: String, val language: String) fun main() < val data = Json.decodeFromString("""""") println(data) >
Because there is no language attribute in json, an exception will be reported: Exception in thread «main» kotlinx.serialization.MissingFieldException: Field ‘language’ is required for type with serial name ‘example.exampleClasses04.Project’, but it was missing
You can fix this problem by adding default values to properties, such as:
@Serializable data class Project(val name: String, val language: String = "Kotlin") fun main() < val data = Json.decodeFromString("""""") println(data) > Print results: Project(name=kotlinx.serialization, language=Kotlin)
2. Required properties
In deserialization, if you want json to contain the specified attribute name, you can use the @ Required annotation
@Serializable data class Project(val name: String, @Required val language: String = "Kotlin") fun main() < val data = Json.decodeFromString(""" """) println(data) >
In the example, because json does not contain the language attribute marked @ Required, an exception will be reported. Field ‘language’ is Required for type with serial name ‘example. Exampleclasss07. Project’, but it was missing
3. JSON property settings
Json < prettyPrint = true //json formatting isLenient = true //Loose parsing, json format exceptions can also be parsed, such as: ignoreUnknownKeys = true //Ignore unknown keys, such as - > person (Val Name: String) coerceInputValues = true //Forced input value. If the json attribute does not match the object format, the object default value is used, such as: + Person(val name:String =" little green ", Val age: int = 18) - > person (" little red ", 18) encodeDefaults = true //Encode the default value. By default, the attribute of the default value will not participate in serialization. By setting encodeDefaults = true, the default attribute can participate in serialization (refer to the above example) explicitNulls = true //Ignore null when serializing allowStructuredMapKeys = true //Allow structured mapping (map key s can use objects) allowSpecialFloatingPointValues = true //Special floating point value: Double is allowed to be NaN or infinity >
Posted by messels on Thu, 07 Oct 2021 21:05:58 -0700
Hot Keywords
- Java — 6961
- Database — 2683
- Python — 2616
- Programming — 2419
- Attribute — 2418
- Javascript — 2383
- Spring — 2111
- Android — 2077
- xml — 1972
- Linux — 1818
- JSON — 1764
- network — 1748
- github — 1720
- less — 1676
- MySQL — 1538
- SQL — 1332
- PHP — 1318
- encoding — 1179
- Mobile — 1029
- Apache — 925
Kotlin JSON serialization crash course
So you want to quickly convert your Data classes to JSON and vice-versa. That should be easy to do. JSON has been around for ages.
In Android (and in the Java world in general) this was traditionally «outsourced» to a dedicated library. In the past, this used to be the Gson library. But lately, especially with Kotlin’s null-aware type system, the library fell out of grace.
There are other modern JSON libraries out there (e.g. Moshi). And Kotlin, since version 1.3, provides its own way way for serializing to and from JSON (and other formats, like protobuf — maybe in another post).
Set up
Kotlin’s own way is a compiler plugin with a runtime dependency. You would need to modify your build.gradle a bit, but after that is super easy.
[. ] apply plugin: 'kotlinx-serialization' [. ] dependencies
Check out the official doc for the latest runtime version.
Usage
Prepare your data classes
You would need to annotate your data classes with @Serializabe . Note that you can annotate regular classes as well, but there is more limitation on what is supported.
@Serializable data class MyThing( val data: List, val success: Boolean )
Notice that if we are serializing a data class that refers to other data classes, the «child» classes should be @Serializable as well.
Serialize/Deserialize
Converting from and to JSON is quite easy.
val myThing: MyThing = Json.parse(MyThing.serializer(), myThingInJsonText)
val myThingInJsonText: String = Json.stringify(MyThing.serializer(), myThing)
The Json static object we are accessing provides the default configuration for the serialization. This configuration, according to the docs, is sensible but it’s not guaranteed never to change. So for avoiding unpleasant surprises, you can get your instance with the stable configuration, for guranating that whatever works today will work tomorrow. Check out the doc for more details.
val json = Json(JsonConfiguration.Stable) json.parse(. ) json.stringfy(. )
Ignore and optional fields
It’s common to have some optional fields. Or fields that you just don’t want to use for serialization/deserialization. For optionals, just set a default value and it will be overridden if there’s a value in the JSON.
@Serializable data class MyThing( val data: List, val success: Boolean = false )
For ignoring a field, just annotate with @Transient .
@Serializable data class MyThing( val data: List, @Transient val success: Boolean )
This post was just a scratch on the surface. You can customize the serialization process whatever your needs are.
On how to convert your JSON to data classes, check out this post. Now enjoy your JSON conversion!
Сериализация Kotlin с помощью Kotlinx.Serialization
После работы над мультиплатформенной библиотекой, которая собирала .framework и .aar артефакты, я пришел к выводу, что есть большое количество полезных вещей, уже есть в Kotlin, но многие из нас никогда о них не знали.
Одна из вещей, о которой вы обязательно должны позаботиться при создании мультиплатформенного проекта — это библиотеки, которые вы используете при разработке. Лучше всего стоит придерживаться решений, предоставленных Kotlin «из коробки».
Так, когда я попал в ситуацию, когда появилась необходимость сериализовать JSON документ, который нужно было использовать на двух платформах(iOS и Android), появились проблемы в компиляции проекта под iOS. После небольших поисков, я нашёл Kotlinx Serializtion library.
Если быть откровенным, я никогда не знал об этой библиотеки, так что эта публикация в большей степени для людей, которые так же как и я не знали об этом инструменте.
Процесс настройки проекта для использования плагина достаточно хорошо описан в репозитории на Гитхабе. Но я буду настраивать проект как для Android, так и для мультиплатформенного использования.
Единственное, что надо сделать при мультиплатформенной компиляции, нужно добавить зависимости в конец зависитмостей в вашем нативном grandle файле.
implementation org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1
Пример Grundle для мультиплатформенного использования
plugins < id 'kotlin-multiplatform' version '1.3.11' id 'kotlinx-serialization' version '1.3.10' >repositories < google() jcenter() mavenCentral() maven < url "https://kotlin.bintray.com/kotlinx" >> apply plugin: 'com.android.library' apply plugin: 'kotlin-android-extensions' android < compileSdkVersion 28 defaultConfig < minSdkVersion 15 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" >buildTypes < release < minifyEnabled false >> > dependencies < implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' androidTestImplementation 'com.android.support.test:runner:1.0.2' >kotlin < targets < fromPreset(presets.android, 'android') // Пресет для эмулятора iPhone // Поменяйте гп presets.iosArm64 (или iosArm32) чтобы собрать библиотеку для iPhone fromPreset(presets.iosX64, 'ios') < compilations.main.outputKinds('FRAMEWORK') >> sourceSets < commonMain < dependencies < implementation 'org.jetbrains.kotlin:kotlin-stdlib-common' implementation 'org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1' >> commonTest < dependencies < implementation 'org.jetbrains.kotlin:kotlin-test-common' implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common' >> androidMain < dependencies < implementation 'org.jetbrains.kotlin:kotlin-stdlib' >> androidTest < dependencies < >> iosMain < dependencies< implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.9.1" >> iosTest < >> >
Для Android
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlinx-serialization' android < compileSdkVersion 28 defaultConfig < applicationId "com.example.smile.kotlinxretrosample" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" >buildTypes < release < minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' >> > dependencies
Сериализация
Чтобы сериализировать класс, просто добавьте перед ним аннотацию @Serializable
import kotlinx.serialization.Serializable @Serializable class Field
Серилиазация работает и с классами данных
Теперь, попробуем написать небольшой пример для преобразования JSON в объект и обратно.
/* * < length = 20 hint = "example" required= false >*/ fun toObject(stringValue: String): Field < return JSON.parse(Field.serializer(), stringValue) >fun toJson(field: Field): String < // Обратите внимание, что мы вызываем Serializer, который автоматически сгенерирован из нашего класса // Сразу после того, как мы добавили аннотацию @Serializer return JSON.stringify(Field.serializer(), field) >
@Transient и @Optional
Еще две аннотации о который стоит рассказать это:
- @Transient — Покажет Serializer’y что поле нужно проигнорировать.
- @Optional — Serializer не остановиться и не выкинет ошибку, если поле отсутствует, но в тоже самое время значение по-умолчанию все равно должно быть установлено.
@Optional var isOptional: Boolean = false @Transient var isTransient: Boolean = false
Пример для Android с использованием Retrofit
Для тех, кто хочет использовать этот плагин в разработке для Андроида, Retrofit 2 имеет адаптер. Ссылка на адаптер.
un createRetrofit(): Retrofit < val contentType = MediaType.get("application/json") return Retrofit.Builder() .addConverterFactory(serializationConverterFactory(contentType, JSON)) .baseUrl(BASE_URL) .client(provideOkhttpClient()) .build() >
Если ваш класс уже имеет аннотации, то после отправки запроса ваш класс должен превратиться в JSON объект.
В общем, сериализация в Kotlin’e является отличным дополнением для любого проекта и делает сам процесс сохранения данных в строчке или JSON объекте гораздо более простым менее трудозатратным.
Список репозиториев
- KotlinxRetrofit — небольшой работащий пример использования сериализации на Android
- kotlinx.serialization — Основной репозиторий библиотеки