1

I'm trying to make all keys in a json object formatted in PascalCase when serializing a case class. It looks like the right way to do this is to define a CustomKeySerializer from the org.json4s package and reformat keys as I wish. However, while I am able to get a CustomSerializer to work, I'm not able to get a CustomKeySerializer to actually get used when serializing a case class (with nested case classes of unknown types). My code looks like the following:

case object PascalCaseSerializer extends CustomKeySerializer[String](format => (
  { case _ => "this is the deserializer and I don't need it" },
  { case _ => "this does nothing" }
))
implicit val formats: Formats = DefaultFormats + PascalCaseSerializer

case class Foo(thingId: Int, eventData: Any)
case class Bar(numThings: Int)
val event = Foo(1, Bar(2))

val payloadJson = write(event) // """{"thingId":1,"eventData":{"numThings":2}}"""

What am I missing here?

jdrub
  • 13
  • 4

1 Answers1

0

It looks like you will have to use CustomSerializer. If you look at the Extraction.scala source at internalDecomposeWithBuilder, you may notice a piece of code that looks like:

    while(iter.hasNext) {
      iter.next() match {
        case (k: String, v) => addField(k, v, obj)
        case (k: Symbol, v) => addField(k.name, v, obj)

        ...

        case (k, v) => {
          val customKeySerializer = formats.customKeySerializer(formats)
          if(customKeySerializer.isDefinedAt(k)) {
            addField(customKeySerializer(k), v, obj)
          } else {
            fail("Do not know how to serialize key of type " + k.getClass + ". " +
              "Consider implementing a CustomKeySerializer.")
          }
        }
      }
    }

It means that you can't use CustomKeySerializer[String] to override default behavior for String keys. You can only use CustomKeySerializer to add some behavior for key types not explicitly defined in this pattern matching.

SergGr
  • 23,570
  • 2
  • 30
  • 51