0

If I try to serialize the case class:

case class C(map: Map[Boolean, String])

I get the exception:

org.json4s.package$MappingException: Do not know how to serialize key of type class java.lang.Boolean. Consider implementing a CustomKeySerializer

I cannot find any documentation anywhere as to how I should implement a CustomKeySerializer. Could someone point me to a guide?

user79074
  • 4,937
  • 5
  • 29
  • 57
  • I think there is the same reason as in question https://stackoverflow.com/questions/64914995/cannot-deserialize-a-tuple/64931695 `boolean` can't be a key in JSON-objects, but in serialized `C` it would be in key: `{ "map" : { true : "some_string", false : "antoher_one" } }` but is is invalid. I would advice do not use `Boolean` as key type in serialized to JSON structures. – Boris Azanov Nov 20 '20 at 15:22
  • The error message is misleading. You don't implement CustomKeySerializer, you just create new instance and add it to you formats. Check its constructor signature. – Nebril Jan 28 '21 at 16:26
  • 1
    Can you please create [mre]? It is hard to answer it like this. – Tomer Shetah Jan 28 '21 at 16:30

1 Answers1

1

According to json standard, keys of an object must be strings, and a String must be wrapped with quotes.

If you want to convert a supported type, you can simply do:

case class C1(map: Map[String, Boolean]) {
  val json = "map" -> map
}
val c1 = C1(Map("true" -> true, "false" -> false))
println(pretty(render(c1.json)))

The output is:

{
  "map":{
    "true":true,
    "false":false
  }
}

But if you want to convert an unsupported type, you need to make the conversion yourself. For example you can do:

case class C(map: Map[Boolean, String]) {
  val json = "map" -> map.map(kvp => (kvp._1.toString, kvp._2))
}
val c = C(Map(true -> "true", false -> "false"))
println(pretty(render(c.json)))

And the output is:

{
  "map":{
    "true":"true",
    "false":"false"
  }
}

In order to do all of that you need to import:

import org.json4s.native.JsonMethods._
import org.json4s.JsonDSL._

Code run at Scastie.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35