Карта [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))