spray-json 中的递归数据类型和自定义序列化程序
Recursive data types and custom serializers in spray-json
我有一个递归数据结构,我想为其编写自定义 spray-json 序列化程序。
case class Counts(var count: Int, var properties: mutable.Map[String, Counts])
object MyJsonProtocol extends DefaultJsonProtocol {
import DefaultJsonProtocol._
implicit object CountsJsonFormat extends RootJsonFormat[Counts] {
def read(json: JsValue) = ???
def write(c: Counts) = {
// Flatten count and properties into the same object.
val properties = c.properties.toJson.asJsObject
val fields = properties.fields + ("count" -> JsNumber(c.count))
JsObject(fields.toSeq: _*)
}
}
}
如果您使用内置序列化逻辑,我已经看过有关如何针对案例 class 执行此操作的文档,但我不知道如何将其应用于自定义序列化程序。我收到此编译器错误:
Cannot find JsonWriter or JsonFormat type class for scala.collection.mutable.Map[String,co.asku.acuity.EventCounter.Counts]
val properties = c.properties.toJson.asJsObject
^
默认情况下,spray-json 格式无法处理可变地图(参见 this disussion 不久前在邮件列表中发生的事情)。将 properties
的类型更改为不可变 Map(我认为这样更好),您的格式将按预期工作。
添加到 edi 的答案中,使用 toMap
可以在我发布的示例中工作,将可变映射转换为不可变映射。
但是,我实际上 运行 使用嵌套可变映射进入更复杂的用例,所以我只是添加了一种格式来像这样序列化它们:
object JsonProtocol extends DefaultJsonProtocol {
import DefaultJsonProtocol._
implicit def mutableMapFormat[K :JsonFormat, V :JsonFormat] = new RootJsonFormat[mutable.Map[K, V]] {
def read(value: JsValue) = ???
def write(m: mutable.Map[K, V]) = m.toMap.toJson
}
implicit object CountsJsonFormat extends RootJsonFormat[Counts] {
// ...
}
}
我有一个递归数据结构,我想为其编写自定义 spray-json 序列化程序。
case class Counts(var count: Int, var properties: mutable.Map[String, Counts])
object MyJsonProtocol extends DefaultJsonProtocol {
import DefaultJsonProtocol._
implicit object CountsJsonFormat extends RootJsonFormat[Counts] {
def read(json: JsValue) = ???
def write(c: Counts) = {
// Flatten count and properties into the same object.
val properties = c.properties.toJson.asJsObject
val fields = properties.fields + ("count" -> JsNumber(c.count))
JsObject(fields.toSeq: _*)
}
}
}
如果您使用内置序列化逻辑,我已经看过有关如何针对案例 class 执行此操作的文档,但我不知道如何将其应用于自定义序列化程序。我收到此编译器错误:
Cannot find JsonWriter or JsonFormat type class for scala.collection.mutable.Map[String,co.asku.acuity.EventCounter.Counts]
val properties = c.properties.toJson.asJsObject
^
spray-json 格式无法处理可变地图(参见 this disussion 不久前在邮件列表中发生的事情)。将 properties
的类型更改为不可变 Map(我认为这样更好),您的格式将按预期工作。
添加到 edi 的答案中,使用 toMap
可以在我发布的示例中工作,将可变映射转换为不可变映射。
但是,我实际上 运行 使用嵌套可变映射进入更复杂的用例,所以我只是添加了一种格式来像这样序列化它们:
object JsonProtocol extends DefaultJsonProtocol {
import DefaultJsonProtocol._
implicit def mutableMapFormat[K :JsonFormat, V :JsonFormat] = new RootJsonFormat[mutable.Map[K, V]] {
def read(value: JsValue) = ???
def write(m: mutable.Map[K, V]) = m.toMap.toJson
}
implicit object CountsJsonFormat extends RootJsonFormat[Counts] {
// ...
}
}