Scala Encoding No JSON value using circe

Suppose I have the following case classes that need to be serialized as JSON objects using circe:

@JsonCodec
case class A(a1: String, a2: Option[String])

@JsonCodec
case class B(b1: Option[A], b2: Option[A], b3: Int)

Now I need to encode val b = B(None, Some(A("a", Some("aa")), 5)as JSON, but I want to be able to control whether it is output as

{
  "b1": null,
  "b2": {
          "a1": "a",
          "a2": "aa"
        },
  "b3": 5
}

or

{
  "b2": {
          "a1": "a",
          "a2": "aa"
        },
  "b3": 5
}

Using Printer dropNullKeysconfig, for example. b.asJson.noSpaces.copy(dropNullKeys = true)will cause output to exit None, while setting it to falsewill encode Noneas null( see also this question ). But how can you control this parameter based on the field?

+4
source share
1 answer

, , - B:

import io.circe.{ Decoder, JsonObject, ObjectEncoder }
import io.circe.generic.JsonCodec
import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder }

@JsonCodec
case class A(a1: String, a2: Option[String])
case class B(b1: Option[A], b2: Option[A], b3: Int)

object B {
  implicit val decodeB: Decoder[B] = deriveDecoder[B]
  implicit val encodeB: ObjectEncoder[B] = deriveEncoder[B].mapJsonObject(
    _.filter {
      case ("b1", value) => !value.isNull
      case _ => true
    }
  )
}

:

scala> import io.circe.syntax._
import io.circe.syntax._

scala> B(None, None, 1).asJson.noSpaces
res0: String = {"b2":null,"b3":1}

, JSON ( b1 B).

, @JsonCodec . - - "" , ( ). ( deriveDecoder ), @JsonCodec .

+7

Source: https://habr.com/ru/post/1670357/


All Articles