3

我有以下案例类

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

这些rows是从 Java 库中获得的,该库可以在数组中包含 null 元素,如下所示:

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

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

如何将空元素编码为空字符串(“”)?

4

2 回答 2

6

您可以将自定义解码器用于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(例如翻译nullOption.None)。

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

implicit val encodeFoo: Encoder[String] = {
  case null => Json.fromString("")
  case s    => Json.fromString(s)
}
于 2017-12-14T20:31:32.383 回答
2

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

implicit val encodeString = 
  Encoder.encodeString.contramap[String](s => if (s == null) "" else s)
于 2018-11-17T19:35:35.663 回答