scalaserializationdeserializationjson4s

json4s, how to deserialize json with FullTypeHints w/o explicitly setting TypeHints


I do specify FullTypeHints before deserialization

 def serialize(definition: Definition): String = {
    val hints = definition.tasks.map(_.getClass).groupBy(_.getName).values.map(_.head).toList
    implicit val formats = Serialization.formats(FullTypeHints(hints))
    writePretty(definition)
  }

It produces json with type hints, great!

{
  "name": "My definition",
  "tasks": [
    {
      "jsonClass": "com.soft.RootTask",
      "name": "Root"
    }
  ]
}

Deserialization doesn't work, it ignores "jsonClass" field with type hint


  def deserialize(jsonString: String): Definition = {
    implicit val formats = DefaultFormats.withTypeHintFieldName("jsonClass")
    read[Definition](jsonString)
  }

Why should I repeat typeHints using Serialization.formats(FullTypeHints(hints)) for deserialization if hints are in json string?

Can json4s infer them from json?


Solution

  • The deserialiser is not ignoring the type hint field name, it just does not have anything to map it with. This is where the hints come in. Thus, you have to declare and assign your hints list object once again and pass it to the DefaultFormats object either by using the withHints method or by overriding the value when creating a new instance of DefaultFormats. Here's an example using the latter approach.

    val hints = definition.tasks.map(_.getClass).groupBy(_.getName).values.map(_.head).toList
    implicit val formats: Formats = new DefaultFormats {
        outer =>
            override val typeHintFieldName = "jsonClass"
            override val typeHints = hints
    }