Я нашел достаточно удобный способ сделать это с помощью Spray Json
Сначала мы определим способ получить JsObject
из Map[String, Any]
def mapToJsObject(map: Map[String, Any]): JsObject =
JsObject(fields = map.mapValues(anyToJsValue))
def anyToJsValue(any: Any): JsValue = any match {
case n: Int => JsNumber(n)
case n: Long => JsNumber(n)
case n: Double => JsNumber(n)
case s: String => JsString(s)
case true => JsTrue
case false => JsFalse
case null | None => JsNull
case list: List[_] => JsArray(list.map(anyToJsValue).toVector)
case Some(any) => anyToJsValue(any)
case map: Map[String, Any] => mapToJsObject(map)
}
Затеммы можем просто использовать convertTo
при условии, что у нас есть неявное JsonFormat
в области действия
case class Address(street: String, zip: Int)
case class Person(name: String, address: Address)
implicit val addressFormat = jsonFormat2(Address.apply)
implicit val personFormat = jsonFormat2(Person.apply)
"Convert Person example map to Person JsObject" in {
JsonUtils.mapToJsObject(
Map(
"name" -> "Tom",
"address" -> Map("street" -> "Jefferson st", "zip" -> 10000)
)
).convertTo[Person] must_=== Person("Tom", Address("Jefferson st", 10000))
}
CAVEATs
Спрей json имеет из коробки только jsonFormat до 22 полей!
Не может обрабатывать любые пользовательские типы, например java.sql.Timestamp
, так как это не тип JSON.