scala - Circe:强制可选字段为 `null`

标签 scala circe

有没有办法将单个 None 字段序列化为“null”?

例如:

// When None, I'd like to serialize only f2 to `null`
case class Example(f1: Option[Int], f2: Option[Int])
val printer = Printer.noSpaces.copy(dropNullValues = true)

Example(None, None).asJson.pretty(printer) === """{"f2":null}"""

最佳答案

您可以通过将过滤器映射到编码器的输出(可以使用 Encoder.forProductN 等导出、定义)来非常简单地完成此操作:

import io.circe.{ Json, ObjectEncoder }
import io.circe.generic.semiauto.deriveEncoder

case class Example(f1: Option[Int], f2: Option[Int])

val keepSomeNulls: ((String, Json)) => Boolean = {
  case ("f1", v) => !v.isNull
  case (_, _) => true
}

implicit val encodeExample: ObjectEncoder[Example] =
  deriveEncoder[Example].mapJsonObject(_.filter(keepSomeNulls))

然后:

scala> import io.circe.syntax._
import io.circe.syntax._

scala> Example(Some(1), Some(2)).asJson.noSpaces
res0: String = {"f1":1,"f2":2}

scala> Example(Some(1), None).asJson.noSpaces
res1: String = {"f1":1,"f2":null}

scala> Example(None, Some(2)).asJson.noSpaces
res2: String = {"f2":2}

scala> Example(None, None).asJson.noSpaces
res3: String = {"f2":null}

请注意,将打印机配置为删除 null 值仍会删除此处的 "f2": null。这是我认为一般情况下最好将空值的保存完全由打印机负责的部分原因,但在这种情况下,空值字段的存在或不存在显然在语义上是有意义的,因此您可以必须混合级别。

关于scala - Circe:强制可选字段为 `null`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55229399/

相关文章:

即使 Json.toString 返回正确的值,Json.asString 也返回 None

scala - Circe 从蛇盒键解析 json

json - 带有泛型的 Scala Circe

java - Play Framework - 尝试映射 Promise 时无法解析 ExecutionContext

scala - Scala 中的 Monad 变形金刚

scala - scala中的类别名

scala - 使用 Circe 解码 Normal Class(不是 case class)

scala - 大型 Docker 上下文会减慢 docker-compose 构建速度

java - 获取 sbt 插件时为 “PKIX path building failed” 和 “unable to find valid certification path to requested target”

json - 使用 Circe 在 Scala 中将 null 值映射到 None