In this section, we will look at the kotlinx.serialization library. This consists of three parts:
- Plugin
- Compiler
- Library
To make a class serializable, we should mark it with the @Serializable annotation:
@Serializable
data class Person(
val id: Int = 0,
val first_name: String,
val last_name: String,
val phones: List<String> = listOf()
)
We can serialize an instance of this class to JSON by using the following code:
fun main(args: Array<String>) {
println(JSON.stringify(Person(first_name = "Igor", last_name = "Kucherenko")))
}
The output looks like this:
{"id":0,"first_name":"Igor","last_name":"Kucherenko","phones":[]}
We can deserialize JSON by using the following code:
val jsonPerson = """{"id":0,"first_name":"Igor","last_name":"Kucherenko","phones":[]}"""
println(JSON.parse<Person>(jsonPerson))
The output looks like this:
Person(id=0, first_name=Igor, last_name=Kucherenko, phones=[])
The following example code demonstrates that we can work with lists without any problem:
fun main(args: Array<String>) {
val jsonPerson = JSON.stringify(Person(first_name = "Igor", last_name = "Kucherenko", phones = listOf("+34434344343", "+33434344242")))
println(jsonPerson)
println(JSON.parse<Person>(jsonPerson))
}
This is the output:
{"id":0,"first_name":"Igor","last_name":"Kucherenko","phones":["+34434344343","+33434344242"]}
Person(id=0, first_name=Igor, last_name=Kucherenko, phones=[+34434344343, +33434344242])
If you want to print JSON in a classic pretty-printed multiline style, you can use the following code:
val jsonPerson = JSON.indented.stringify(Person(firstName = "Igor", lastName = "Kucherenko", phones = listOf("+354445545454", "+433443343443")))
println(jsonPerson)
The output looks like this:
{
"id": 0,
"firstName": "Igor",
"lastName": "Kucherenko",
"phones": [
"+354445545454",
"+433443343443"
]
}
You can also use the @SerialName annotation for overriding a property name. The following example code shows a case such as this:
@Serializable
data class Person(
val id: Int = 0,
@SerialName("first_name") val firstName: String,
@SerialName("last_name") val lastName: String,
val phones: List<String> = listOf()
)
The firstName and lastName properties will look like first_name and last_name in JSON. To serialize and deserialize this in an instance of this class, we will use the following code:
fun main(args: Array<String>) {
val jsonPerson = JSON.indented.stringify(Person(
firstName = "Igor",
lastName = "Kucherenko",
phones = listOf("+354445545454", "+433443343443")))
println(jsonPerson)
println(JSON.parse<Person>(jsonPerson))
}
The following is the output:
{
"id": 0,
"first_name": "Igor",
"last_name": "Kucherenko",
"phones": [
"+354445545454",
"+433443343443"
]
}
Person(id=0, firstName=Igor, lastName=Kucherenko, phones=[+354445545454, +433443343443])
......
We can also use custom serializers and deserializers. Let's say that we want to serialize an instance of the Person class to JSON that contains the name property instead of first_name and last_name. For this, we can create our own saver, which may look as follows:
val saver = object : KSerialSaver<Person> {
override fun save(output: KOutput, obj: Person) {
@Serializable
data class JSONPerson(val id: Int, val name: String, val phones: List<String>)
output.write(JSONPerson(obj.id, "${obj.firstName} ${obj.lastName}", obj.phones))
}
}
We can also use this object like this:
val jsonPerson = JSON.indented.stringify(saver, Person(
firstName = "Igor",
lastName = "Kucherenko",
phones = listOf("+354445545454", "+433443343443")))
println(jsonPerson)
The following is the output:
{
"id": 0,
"name": "Igor Kucherenko",
"phones": [
"+354445545454",
"+433443343443"
]
}