【问题标题】:Scala & Circe: JSON encoding with optional fieldsScala & Circe:带有可选字段的 JSON 编码
【发布时间】:2020-07-20 14:31:32
【问题描述】:

我正在尝试使用 Circe 进行一些 JSON 编码,如下所示:

import io.circe.{Encoder, Json}
import io.circe.syntax._

case class Person(name: String, nickname: Option[String] = None)

object EncodingTest extends App {
  val persons = List (Person("John", None), Person("Tania", Some("Awesome")))

  implicit val encodePerson: Encoder[Person] = (p: Person) => {
    Json.obj(
      ("name", Json.fromString(p.name)),
      ("nickname", Json.fromString(p.nickname.getOrElse(""))) // <- Problem is here
    )
  }

  for(person <- persons)
    println(person.asJson)
}

理想情况下,我希望得到以下输出:

{"name":"John"}
{"name":"Tania","nickname":"Awesome"}

如果字段值为None,如何让编码器跳过nickname字段?

【问题讨论】:

  • 您可以使用自动派生,因此 circe 将为您的案例类创建 EncoderDecoder,并为您提供所需的缺席字段行为:circe.github.io/circe/codecs/auto-derivation.html
  • @IvanKurchenko 感谢您的评论!这将适用于我的实际用例(即不是我粘贴在顶部的过度简化的示例),我在其中定义自定义类型,但最终归结为可以通过自动派生处理的基本类型。

标签: json scala encoding circe


【解决方案1】:

如果您想定义自定义编码器而不依赖 semiauto,则可以使用以下方法

import io.circe.{Encoder, Json}
import io.circe.syntax._

object CirceOptional extends App {

  case class Person(name: String, nickname: Option[String] = None)

  val encodePerson: Encoder[Person] = (p: Person) => {
    Json.obj(("name", p.name.asJson), ("nickname", p.nickname.asJson))
  }

  implicit val noNullEncoder: Encoder[Person] = encodePerson.mapJson(_.dropNullValues)

  val persons = List (Person("John", None), Person("Tania", Some("Awesome")))

  for(person <- persons)
    println(person.asJson)

}

【讨论】:

    【解决方案2】:

    简单的方法是只收集您感兴趣的字段

    Json.obj(List(
      ("name", Some(Json.fromString(p.name))),
      ("nickname", p.nickname.map(Json.fromString))
    ).collect {
      case (name, Some(value)) => name -> value
    }: _*)
    

    更自动的方式来获得你想要的东西:

    import io.circe.generic.semiauto._
    implicit val encodePerson: Encoder[Person] = deriveEncoder
    person.asJson.dropNullValues
    

    【讨论】:

      猜你喜欢
      • 2017-09-01
      • 2020-05-03
      • 2017-07-10
      • 2014-04-12
      • 1970-01-01
      • 2020-06-05
      • 2021-06-05
      • 2018-10-22
      • 2018-07-18
      相关资源
      最近更新 更多