Scala使用circe将None编码为NaN json值
Posted
技术标签:
【中文标题】Scala使用circe将None编码为NaN json值【英文标题】:Scala encoding None to NaN json value with circe 【发布时间】:2021-06-05 15:56:35 【问题描述】:我有一个通过 HTTP 调用 TensorFlow 服务的 scala 服务。 我正在尝试使用 circe 将 None 值编码为 NaN 作为 JSON(TensorFlow 的预期方式),但是在编码对象后我得到“null”
假设我有以下需要使用 circe 序列化为 JSON 对象的案例类:
case class MyRequest(instance: Option[Double])
object MyRequest extends CirceDefaults
implicit val autoEncoderRequestEncoder: Encoder[MyRequest] = (myRequest: MyRequest) =>
myRequest.instance match
case Some(value) => Json.fromDouble(value).asJson
case None => None.asJson
所以 None.asJson 编码为“null”而不是 NaN 并且我从 tensorflow 服务收到错误:
错误:无效参数:JSON 值:“null”类型:字符串不是预期类型:float”
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:这是默认的 Circe 行为。详情请查看:https://github.com/circe/circe/issues/1267
而且似乎不仅适用于 Circe,而且一般 JSON 标准没有 Nan、-Infinity、+Infinity 这样的东西,所以在 Circe 中,您甚至无法为 Double.Nan
创建 Json:https://github.com/circe/circe/blob/master/modules/core/shared/src/main/scala/io/circe/Json.scala#L517
所以Json.fromDouble(Double.Nan)
返回None
- 因为Double.Nan
不是真实的:https://github.com/circe/circe/blob/master/modules/core/shared/src/main/scala/io/circe/Json.scala#L575
因此,不幸的是,为了以您想要的方式渲染 Nan
,您需要在渲染后编辑 JSON 字符串
import io.circe._, io.circe.generic.semiauto._, io.circe.syntax._
case class MyRequest(instance: Option[Double])
object MyRequest
implicit val encoder: Encoder[MyRequest] = request =>
request.instance.fold(Json.fromString("NaN"))(_.asJson)
case class BigRequest(request: MyRequest)
object BigRequest
implicit val encoder: Encoder[BigRequest] = deriveEncoder[BigRequest]
println(BigRequest(MyRequest(Some(1.0d))).asJson.noSpaces)
println(BigRequest(MyRequest(None)).asJson.noSpaces.replace(""""NaN"""", "NaN"))
斯卡蒂:https://scastie.scala-lang.org/SGHtB9GZRpShtQ6A8qAZsA
【讨论】:
以上是关于Scala使用circe将None编码为NaN json值的主要内容,如果未能解决你的问题,请参考以下文章
Circe Scala - 编码和解码 Map[] 和案例类
使用 circe 在 Scala 中 JSON 将嵌套字段解码为 Map[String, String]