【问题标题】:How to decode null to empty string in Circe如何在Circe中将null解码为空字符串
【发布时间】:2018-05-28 23:53:30
【问题描述】:

我有以下案例类

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

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

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

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

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

【问题讨论】:

    标签: scala circe


    【解决方案1】:

    您可以为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)
    }
    

    【讨论】:

    • 感谢您的回答。如果我们必须进行迭代,那么我可以直接创建 newRows 并将 null 值替换为 "" 然后使用 Response(attributes, newRows).asJson.noSpaces
    • 通常你应该避免在 Scala 中使用null。您可以使用Option.None 来表示null 值。如果您需要更多输入,我可以将其添加到我的答案中。告诉我。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-06-02
      • 1970-01-01
      • 2013-09-27
      • 2011-10-09
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      相关资源
      最近更新 更多