如何在Circe中将null解码为空字符串

时间:2017-12-14 19:49:26

标签: scala circe

我有以下案例类

case class Response(attributes: CsvAttributes, rows: Seq[Array[String]])

rows从Java库中获取,该库可以在数组中包含null元素,如下所示:

[
  ["a", "b", null],
  ["c", null, "d"]
]

Response(attributes, rows).asJson.noSpaces抛出错误。

如何将null元素编码为空字符串("")?

2 个答案:

答案 0 :(得分:3)

您可以为Response使用自定义解码器:

implicit val decodeResponse: Decoder[Response] = (c: HCursor) =>
  for {
    attributes <- c.downField("attributes").as[CsvAttributes]
    rows       <- c.downField("rows").as[Seq[Array[Option[String]]]]
  } yield {
    Response(attributes, rows.map(_.map {
      case Some(v) => v
      case None    => ""
    }))
  }

我会尝试将您的Java库的响应转换为惯用的Scala(例如将null翻译为Option.None)。

但是如果你想避免这种情况,你可以覆盖circe编码String的默认行为。此声明会将其更改为使用空字符串表示null

implicit val encodeFoo: Encoder[String] = {
  case null => Json.fromString("")
  case s    => Json.fromString(s)
}

答案 1 :(得分:1)

另一种快速而肮脏的方法是:

implicit val encodeString = 
  Encoder.encodeString.contramap[String](s => if (s == null) "" else s)