首页 > 解决方案 > Scala & Circe:带有可选字段的 JSON 编码

问题描述

我正在尝试使用 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"}

nickname如果字段值为 ,如何使编码器跳过该字段None

标签: jsonscalaencodingcirce

解决方案


如果您想定义自定义编码器而不依赖 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)

}

推荐阅读