Let's say I have the next case class:
case class Person(id: String, money: BigDecimal)
object Person {
implicit val encoder: Encoder[Person] = Encoder.forProduct2("ID", "Money")(u =>
(u.id, u.money))
I want to serialize instances of the Person class to JSON, so when I evaluate the asJson
from circe, I get the result in scientific notation:
{
"ID" : "123",
"VALOR_SAP" : 2.7E+7
}
Why do this happens? I think the reason is because the default to string of BigDecimal
automatically format to scientific notation.
What could I do to avoid this? May be creating another type which extends from BigDecimal
and overriding the toString
?
I assume that you use scala.math.BigDecimal
, for java.math.BigDecimal
code is similar. The way to change how objects are serialized is to provide corresponding implicit Encoder
object. Unfortunately both Json
and JsonNumber
hierachies are sealed, so there is no very clean solution but you still can use JsonNumber.fromDecimalStringUnsafe
that implements toString
to just return any string you passed in. So you can do something like this:
case class Person(id: String, money: BigDecimal)
object Person {
implicit final val bigDecimalAsPlainStringEncoder: Encoder[BigDecimal] = new Encoder[BigDecimal] {
final def apply(value: BigDecimal): Json = Json.fromJsonNumber(JsonNumber.fromDecimalStringUnsafe(value.bigDecimal.toPlainString))
}
implicit val encoder: Encoder[Person] = Encoder.forProduct2("ID", "Money")(u => (u.id, u.money))
}