jsonscalajson4s

HowTo skip deserialization for a field in json4s


Here is my json:

{
  "stringField" : "whatever",
  "nestedObject": { "someProperty": "someValue"}
}

I want to map it to

case class MyClass(stringField: String, nestedObject:String)

nestedObject should not be deserialized, I want json4s to leave it as string.

resulting instance shouldBe:

val instance = MyClass(stringField="whatever", nestedObject= """ { "someProperty": "someValue"} """)

Don't understand how to do it in json4s.


Solution

  • You can define a custom serializer:

    case object MyClassSerializer extends CustomSerializer[MyClass](f => ( {
      case jsonObj =>
        implicit val format = org.json4s.DefaultFormats
        val stringField = (jsonObj \ "stringField").extract[String]
        val nestedObject = compact(render(jsonObj \ "nestedObject"))
    
        MyClass(stringField, nestedObject)
    }, {
      case myClass: MyClass =>
        ("stringField" -> myClass.stringField) ~
          ("nestedObject" -> myClass.nestedObject)
    }
    ))
    

    Then add it to the default formatter:

    implicit val format = org.json4s.DefaultFormats + MyClassSerializer
    println(parse(jsonString).extract[MyClass])
    

    will output:

    MyClass(whatever,{"someProperty":"someValue"})
    

    Code run at Scastie