我有相关演员的消息(de)可以序列化为Play游戏! JSON。我想为akka persistance系统使用JSON(de)序列化器(如果可能的话)。
在akka persistance文档中,可以使用我们自己的序列化程序。更多here是如何编写自定义序列化程序的说明。由于akka.serialization.Serializer期待toBinary
和fromBinary
,有没有办法使用具有akka持久性的Play JSON序列化程序?
谢谢!
最佳!
答案 0 :(得分:0)
您希望将数据序列化到哪里? 我正在寻找一个基于mongodb的akka持久性存储,它使用我自己的json格式的序列化对象。也许以下驱动程序也可能对您有意义: https://github.com/scullxbones/akka-persistence-mongo/issues/16
答案 1 :(得分:0)
将play json集成到akka-persistence中非常复杂,因为play json使用Format
实例,这些实例是通过隐式收集的。 Akka仅提供java.lang.Object
进行序列化,并提供java.lang.Class[_]
进行反序列化,这使得解析正确的隐式Format
成为不可能。
您可以做的是编写一个自定义akka.serialization.Serializer
,该自定义Map
从Class[A]
到Format[A]
。该地图可用于为java.lang.Object
/ java.lang.Class[_]
查找正确的格式:
class JsonSerializer(serializers: Map[Class[_], Format[_]]) extends Serializer {
val charset: Charset = StandardCharsets.UTF_8
val identifier: Int = "play-json-serializer".##
val includeManifest: Boolean = true
def serializer[A](c: Class[_]): GenericFormat[A] = serializers.get(c) match {
case Some(format) => format.asInstanceOf[GenericFormat[A]]
case None => throw new RuntimeException("No Format available for " + c.getName)
}
def toBinary(o: AnyRef): Array[Byte] = jsonSerialize(o).getBytes(charset)
def fromBinary(bytes: Array[Byte], manifest: Option[Class[_]]): AnyRef = jsonDeserialize(bytes, manifest.get)
def jsonSerialize[A](a: A): String = {
implicit val format: GenericFormat[A] = serializer[A](a.getClass)
Json.stringify(Json.toJson(a))
}
def jsonDeserialize[A](bytes: Array[Byte], manifest: Class[_]): A = {
implicit val format: GenericFormat[A] = serializer[A](manifest)
Json.fromJson[A](Json.parse(new String(bytes, charset))).get
}
}
现在,您可以继承此类并为akka序列化程序应能够将其序列化(反序列化)到构造函数的所有类型传递播放格式。必须在akka配置as described in the documentation中配置此序列化器:
class MyJsonSerializer extends JsonSerializer(Map(
Serializer[Foo], Serializer[...], ...
))
// Just a utility class for the pretty syntax above
object Serializer {
def apply[A](implicit format: Format[A], ctag: ClassTag[A]): (Class[A], Format[A]) =
(ctag.runtimeClass.asInstanceOf[Class[A]], format)
}