Карта [String, Any] для сжатия строки json с использованием json4s

В настоящее время я извлекаю некоторые показатели из разных источников данных и сохраняю их на карте типа Map[String,Any], где ключ соответствует имени метрики, а значение соответствует значению метрики. Мне нужно, чтобы это было более или менее общим, что означает, что типы значений могут быть примитивными типами или списками примитивных типов.

Я хотел бы сериализовать эту карту в строку в формате JSON, и для этого я использую библиотеку json4s. Дело в том, что это не представляется возможным, и я не вижу возможного решения для этого. Я бы ожидал чего-то вроде следующего, чтобы работать из коробки:)

val myMap: Map[String,Any] = ...    // extract metrics
val json = myMap.reduceLeft(_ ~ _)  // create JSON of metrics

Переход через исходный код Я видел, что json4s предоставляет неявные преобразования для преобразования примитивных типов в JValue, а также для преобразования Traversable[A]/Map[String,A]/Option[A] до JValue (при ограничении доступности неявное преобразование от A до JValue, которое я понимаю, на самом деле означает, что A является примитивным типом). Оператор ~ предлагает хороший способ построения JObject out of JField 's, который является просто псевдонимом типа для (String, JValue).

В этом случае тип значений карты равен Any, поэтому неявные преобразования не выполняются и, следовательно, компилятор выдает следующую ошибку:

                    value ~ is not a member of (String, Any)
[error]             val json = r.reduceLeft(_ ~ _)

Есть ли решение для чего я хочу выполнить?

Ответ 1

Поскольку вы на самом деле ищете только строковое представление JSON myMap, вы можете напрямую использовать объект Serialization. Вот небольшой пример (если использование собственной версии json4s изменит импорт на org.json4s.native.Serialization):

EDIT: добавлен formats неявный

 import org.json4s.jackson.Serialization

 implicit val formats = org.json4s.DefaultFormats

 val m: Map[String, Any] = Map(
   "name "-> "joe",
   "children" -> List(
     Map("name" -> "Mary", "age" -> 5),
     Map("name" -> "Mazy", "age" -> 3)
   )
 )
 // prints {"name ":"joe","children":[{"name":"Mary","age":5},{"name":"Mazy","age":3}]}
 println(Serialization.write(m)) 

Ответ 2

json4s имеет для этого метод.

pretty(render(yourMap))