Сериализовать карту [String, Any] с помощью спрея json

Как сериализовать Map[String, Any] с помощью spray-json? я попробую

val data = Map("name" -> "John", "age" -> 42)
import spray.json._
import DefaultJsonProtocol._
data.toJson

Там написано Cannot find JsonWriter or JsonFormat type class for scala.collection.immutable.Map[String,Any].


person Yaroslav    schedule 18.09.2014    source источник


Ответы (2)


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

  implicit object AnyJsonFormat extends JsonFormat[Any] {
    def write(x: Any) = x match {
      case n: Int => JsNumber(n)
      case s: String => JsString(s)
      case b: Boolean if b == true => JsTrue
      case b: Boolean if b == false => JsFalse
    }
    def read(value: JsValue) = value match {
      case JsNumber(n) => n.intValue()
      case JsString(s) => s
      case JsTrue => true
      case JsFalse => false
    }
  }

Он был адаптирован из этого сообщения в группе пользователей Spray, но мне не удалось получить и мне не нужно было писать вложенные последовательности и карты в Json, поэтому я их удалил.

person Gangstead    schedule 18.09.2014
comment
Круто, это работает для меня. Мне просто нужно убедиться, что я объявляю этот объект ПЕРЕД другими имплицитами JsonFormat, которые зависят от него. - person Bogdan; 06.02.2015
comment
И жарко его использовать? Я скопировал этот код над своим immutableMap.toJson. Но все еще получаю Не могу найти писатель Json... ошибка. - person Sergey Yarotskiy; 26.06.2015
comment
Извините, заработало. Похоже, я все еще использовал изменяемую карту, и она должна быть неизменной, чтобы этот пример работал. - person Sergey Yarotskiy; 26.06.2015
comment
Спасибо. Я думаю, вы могли бы просто использовать «case true => JsTrue» и «case false => JsFalse». Проще - никаких функциональных изменений. - person akauppi; 30.06.2015
comment
Мне любопытно, почему это не часть spray-json - person Soid; 24.09.2016
comment
Я использовал код, приведенный в сообщении, на которое есть ссылка, со спреем. json 1.3.3, и он также отлично работает с вложенными элементами. Я предполагаю, что это не включено в spray-json, потому что ему нужно идентифицировать типы элементов во время выполнения, а не во время компиляции... - person aitorhh; 26.10.2017
comment
Я не могу понять, как это работает. Входные данные для записи имеют тип Any. Пока он должен быть типа Map[String,Any]. Я попытался добавить этот код в свою реализацию, для которой требуется только Map[String,String], и он, очевидно, не работает. - person Niko; 24.11.2020

Другой вариант, который должен работать в вашем случае, это

import spray.json._
import DefaultJsonProtocol._

data.parseJson.convertTo[Map[String, JsValue]]
person Emmanuel Ballerini    schedule 14.04.2015
comment
Мне нравится, что вы упомянули об этом, потому что во многих случаях людям может быть достаточно использовать JsValue для значений. Это также больше соответствует менталитету spray.json, имхо, чем обработка Any. - person akauppi; 11.02.2016
comment
data имеет тип Map[String,Any] - что я должен импортировать, чтобы он имел метод parseJson? - person mirelon; 27.07.2016
comment
Я полагаю, что он имел в виду data.toJson - person binshi; 10.05.2018
comment
@mirelon, вероятно, способ датировать комментарий, но для других, читающих это: вы должны убедиться, что import spray.json._ и import DefaultJsonProtocol._ - person pellekrogholt; 03.09.2018
comment
потратил на это целый день. Решение работает как шарм. ...Наконец пора ложиться спать. Большое спасибо. - person shalama; 04.12.2020