我想在scala中序列化扩展类 我有一些测试代码..
import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import play.api.libs.json.Json
@RunWith(classOf[JUnitRunner])
class JsonSerializerTest extends Specification {
class A(val s1: String)
case class B(s2: String) extends A("a")
"Application" should {
"serialize class to JSON" in {
implicit val bWrites = Json.writes[B]
implicit val bReads = Json.reads[B]
val bClass = B("b")
println(bClass.s1 + " " + bClass.s2)
val serialized = Json.toJson[B](bClass)
val s1 = (serialized \ "s1").asOpt[String]
s1 should beSome[String]
}
}
}
在这种情况下测试打印:
a b
Application should
'None' is not Some
java.lang.Exception: 'None' is not Some
这意味着来自父类的s1字段未被序列化。
解决方案
class A(val s1: String)
case class B(override val s1: String, s2: String) extends A(s1)
主要是不可接受的,因为在实际应用程序类中有很多字段,并且每当我扩展类使代码复杂化时都会明确指定它们。
这种情况还有其他解决办法吗?
答案 0 :(得分:0)
您可以手动创建json序列化程序(在此处描述:https://www.playframework.com/documentation/2.5.x/ScalaJsonCombinators)
您的版本的问题是from rq.decorators import job
@job('low', connection=my_redis_conn, timeout=600)
def long_running_task(x, y):
# Code
和Json.writes
是专门查看Json.reads
的构造函数的宏,并从中构建序列化程序(所以超类参数是'n'抓住)。您可以复制并滚动自己的宏版本:https://github.com/playframework/playframework/blob/d6c2673d91d85fd37de424951ee5ad9f4f4cce98/framework/src/play-json/src/main/scala/play/api/libs/json/JsMacroImpl.scala
最后,您可以创建一个取case class
和Json.writes
结果的函数,并添加所需的共享字段。类似的东西:
Json.reads
取决于object A {
def writesSubclass[T](writer: Writes[T]): Writes[T] = new Writes[T] {
def writes(t: T) = Json.obj("s1" -> t.s1) ++ writer.writes(t).as[JsObject]
}
}
implicit val bWrites = A.writesSubclass(Json.writes[B])
延长的频率,这可能是您最好的选择。