如何在 circe JSON 序列化中避免科学记数法

How to avoid scientific notation in circe JSON serialization

假设我有下一个案例 class:

case class Person(id: String, money: BigDecimal)

object Person {
  implicit val encoder: Encoder[Person] = Encoder.forProduct2("ID", "Money")(u =>
    (u.id, u.money))

我想将 Person class 的实例序列化为 JSON,因此当我从 circe 评估 asJson 时,我得到了科学记数法的结果:

{
    "ID" : "123",
    "VALOR_SAP" : 2.7E+7
}

为什么会这样?我认为原因是因为默认为 BigDecimal 的字符串自动格式化为科学计数法。

我该怎么做才能避免这种情况?可能正在创建另一种类型,它从 BigDecimal 扩展并覆盖 toString?

我假设你使用 scala.math.BigDecimal,因为 java.math.BigDecimal 代码是相似的。改变对象序列化方式的方法是提供相应的隐式 Encoder 对象。不幸的是,JsonJsonNumber 层次结构都是密封的,因此没有非常干净的解决方案,但您仍然可以使用 JsonNumber.fromDecimalStringUnsafe 实现 toString 到 return 任何字符串你通过了。所以你可以这样做:

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))

}