Dynamic fields to Json in Scala


We have faced a situation where we needed to create Json representation for a dynamic set of fields & their values which represented by a Map[String, String].

Example:

Scala class

case class Person(name: String, age: String, customFields: Map[String,String])

Default Json representation of above class will be:

{
 "name": "anil",
 "age": "30",
 "customFields": {
     "field1": "value1",
     "field2": "value2"
 }
}

But what we wanted was:

{
 "name": "anil",
 "age": "30",
 "field1": "value1",
 "field2": "value2"
}

This was not very straight forward. While this could be possible using play framework, we didn’t want to complicate things too much. Finally we found a way to do it by returning a Map[String, String] which represents each class (it’s fields & values) using reflection and handle the behavior for custom fields separately.

case class Person(name: String, age: String, customFields:CustomFields)

case class CustomFields(valueMap: Map[String,String])
def covertToMap(ref: AnyRef) =

  ref.getClass.getDeclaredFields.foldLeft(Map[String, Any]()){
    (map, field) => {
      field.setAccessible(true)
      val value = field.get(ref)
      value match {
        case c: CustomFields => {
          map ++ c.valueMap
        }
        case _ => {
          map + (field.getName -> value)
        }
      }
    }
  }

Use the covertToMap() to convert any case class to a Map and then convert this map to normal Json using jackson json4s.

val json = Serialization.write(covertToMap(person))

Complete source code is available here

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s