有没有一种方法可以将单个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}"""
答案 0 :(得分:2)
您可以通过在编码器的输出(可以派生,用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}
请注意,配置打印机以丢弃空值仍会在此处删除"f2": null
。这是我认为一般最好将空值的保留完全由打印机负责的部分原因,但是在这种情况下,存在或不存在空值字段显然在语义上是有意义的,因此您可以必须混合级别。