gpt4 book ai didi

json - 使用 circe 将 Scala None 编码为 JSON 值

转载 作者:行者123 更新时间:2023-12-04 05:36:42 30 4
gpt4 key购买 nike

假设我有以下 case 类需要使用 circe 序列化为 JSON 对象:

@JsonCodec
case class A(a1: String, a2: Option[String])

@JsonCodec
case class B(b1: Option[A], b2: Option[A], b3: Int)

现在我需要编码 val b = B(None, Some(A("a", Some("aa")), 5)作为 JSON 但我希望能够控制它是否输出为
{
"b1": null,
"b2": {
"a1": "a",
"a2": "aa"
},
"b3": 5
}

或者
{
"b2": {
"a1": "a",
"a2": "aa"
},
"b3": 5
}

使用 Printer dropNullKeys 配置,例如 b.asJson.noSpaces.copy(dropNullKeys = true)将导致省略 None s 从输出,而将其设置为 false将编码 None s 为 null ( see also this question )。但是如何在每个字段的基础上控制此设置?

最佳答案

最好的方法可能只是在 B 的半自动衍生编码器中添加一个后处理步骤。 :

import io.circe.{ Decoder, JsonObject, ObjectEncoder }
import io.circe.generic.JsonCodec
import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder }

@JsonCodec
case class A(a1: String, a2: Option[String])
case class B(b1: Option[A], b2: Option[A], b3: Int)

object B {
implicit val decodeB: Decoder[B] = deriveDecoder[B]
implicit val encodeB: ObjectEncoder[B] = deriveEncoder[B].mapJsonObject(
_.filter {
case ("b1", value) => !value.isNull
case _ => true
}
)
}

进而:
scala> import io.circe.syntax._
import io.circe.syntax._

scala> B(None, None, 1).asJson.noSpaces
res0: String = {"b2":null,"b3":1}

您可以调整过滤器的参数以从 JSON 对象中删除您想要的任何空值字段(这里我只是删除 b1 中的 B )。

值得注意的是,目前您不能合并 @JsonCodec注释和伴随对象中明确定义的实例。这不是注释的固有限制——我们可以在宏扩展期间检查伴生对象是否有“覆盖”实例,但这样做会使实现变得更加复杂(现在它非常简单)。解决方法非常简单(只需明确使用 deriveDecoder),但当然我们很乐意考虑请求支持混合和匹配 @JsonCodec 的问题。和显式实例。

关于json - 使用 circe 将 Scala None 编码为 JSON 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42358455/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com