Custom Kotlin Serializer for BigDecimal

Since BigDecimal is part of Java Math and not Kotlin, a custom serializer is needed if you’re not using Jackson. After some thought, I chose to serialize it into a string using KSerializer. This means that you will need to have kolinx.serialization installed. The following is the Kotlin code for the serializer.

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.math.BigDecimal

object BigDecimalSerializer: KSerializer<BigDecimal> {
override fun deserialize(decoder: Decoder): BigDecimal {
return decoder.decodeString().toBigDecimal()
}

override fun serialize(encoder: Encoder, value: BigDecimal) {
encoder.encodeString(value.toPlainString())
}

override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("BigDecimal", PrimitiveKind.STRING)
}

It can be used in data classes like these:

@Serializable
data class Product(
    val id: Long,
    val name: String,
    val description: String,
    @Serializable(with = BigDecimalSerializer::class)
    val cost: BigDecimal,
)

Author: Woo Huiren

Currently a student at National University of Singapore. I contribute to opensource projects - primarily PHP and Angular related. I write about PCF and PWS related stuff too.

2 thoughts on “Custom Kotlin Serializer for BigDecimal”

  1. Hi
    This treats BigInteger/BigDecimal values as strings in serialization; which may not be what one desires.
    For example:

    class MyClass(val myBigInteger: BigInteger)
    val myClass = MyClass(BigInteger(“12345678901234567890”)
    will be serialized as:
    {
    “myBigInteger”: “12345678901234567890”
    }

    and not as:
    {
    “myBigInteger”: 12345678901234567890
    }
    which is what one probably wants.

    1. Thanks for the comment. I forgot to mention that my case is specific to dealing with frontend JavaScript. As JavaScript encodes integers as double precision floating point numbers, it will not give the correct result if it is not a string. In my case, string is actually correct one but for other cases, it might differ.

Leave a Reply