Blog Infos
Author
Published
Topics
,
Author
Published

In this article, we will learn about the major new features that kotlinx.serialization 1.3 brings for developers to manage JSON parsing more efficiently.

We can now read and write JSON directly to network streams or files.

IO stream serialization is currently available only on the JVM platform and for the JSON format.

API includes two main methods:

  • Json.decodeFromStream()
  • Json.encodeToStream()
@Serializable
data class DataModel( // properties )
@OptIn(ExperimentalSerializationApi::class)
fun main() {
URL("https://api.plos.org/search?q=title:DNA").openStream().use {
val jsonData = Json.decodeFromStream<DataModel>(it) // read JSON from a URL
println(jsonData)
FileOutputStream(File("dataModel.json")).use { // save to a file
Json.encodeToStream(jsonData, it)
}
}
}

Java IO stream-based JSON serialization.kt

 

We can force the library to encode the default values by setting the encodeDefaults property of a Json instance to true:

val format = Json { encodeDefaults = true } // false by default

 

  • In 1.3.0 we can control it at the property level by using the experimental @EncodeDefault annotation.
  • It has a higher priority level than the encodeDefaults property.

It has two possible values:

The default value is ALWAYS

  • ALWAYS: encodes a property’s default value.
  • NEVER: doesn’t encode the default value regardless of the Json configuration.
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class Expert(
val id: Int,
val name: String,
val category: Category,
val publishedArticles: Int?,
// @EncodeDefault default ALWAYS
@EncodeDefault val recentEventLink: String? = null
)
enum class Category {
ANDROID, KOTLIN, DART, FLUTTER
}

Property-level control over default value encoding.kt

 

  • explicitNulls: Another way to reduce the size of the generated JSON Strings is by omitting null values.
  • It defines whether null property values should be included in the Serialized JSON String.
  • It’s true by default, so all nulls are stored as the values of their corresponding properties.
val format = Json { explicitNulls = false }
val flutterExpert = Expert(id = 1, "Nav", Category.FLUTTER, null)
val jsonFlutterExpert = format.encodeToString(flutterExpert)
println("EncodedResult: $jsonFlutterExpert")
println("DecodedResult: ${format.decodeFromString<Expert>(jsonFlutterExpert)}")
/*
EncodedResult:
{
"id":1,
"name":"Nav",
"category":"FLUTTER"
}
DecodedResult:
Expert(
id=1,
name=Nav,
category=FLUTTER,
publishedArticles=null,
recentEventLink=null
)
*/

Excluding null values from serialization.kt

 

  • Missing field exception 🥵

To deserialize objects from JSON with omitted nulls, we need to make sure that Json instance with explicitNulls == false is used.

It sets all omitted nullable properties to null unless they have default values.

  • Try to decode a JSON string with omitted nulls with explicitNulls == true (default) it will throw a MissingFieldException
val formatExplicitExcludeNullsFalse = Json { explicitNulls = false }
val flutterExpert = Expert(id = 1, "Roman", Category.FLUTTER, null)
val jsonFlutterExpert = formatExplicitExcludeNullsFalse.encodeToString(flutterExpert)
println("Encoded FlutterExpert result: $jsonFlutterExpert")
val formatExplicitExcludeNullsTrue = Json { explicitNulls = true }
println("Decoded FlutterExpert: ${formatExplicitExcludeNullsTrue.decodeFromString<Expert>(jsonFlutterExpert)}")
/*
Exception in thread "main" kotlinx.serialization.MissingFieldException:
Field 'publishedArticles' is required for type with serial name 'Expert', but it was missing
at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20)
*/

MissingFieldException.kt

 

MissingFieldException

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

  • In hierarchy serialization, a useful attribute comes into play — class discriminator.
  • It stores the exact class of the object that was encoded.
  • By default, it has the name type and contains a fully qualified class name of the object being serialized.

In 1.3.0, By using @JsonClassDiscriminator’s discriminator property we can set a custom discriminator name for each class hierarchy.

@OptIn(ExperimentalSerializationApi::class)
@Serializable
@JsonClassDiscriminator("languageType")
sealed class Language {
abstract val name: String
}
@Serializable
class Kotlin(override val name: String, private val version: String) : Language() {
fun getFormattedVersion(): String {
return version
}
}
@Serializable
class Java(override val name: String) : Language()
/*
Result:
{
"languageType":"Kotlin",
"name":"Kotlin",
"version":"1.5.30"
}
*/

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
Hi, today I come to you with a quick tip on how to update…
READ MORE
blog
Automation is a key point of Software Testing once it make possible to reproduce…
READ MORE
blog
Drag and Drop reordering in Recyclerview can be achieved with ItemTouchHelper (checkout implementation reference).…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu