【发布时间】:2021-01-26 16:19:58
【问题描述】:
寻找一些关于使用 json4s 序列化嵌套案例对象的帮助。皱纹是 case 对象是在运行时决定的,所以看来我需要访问外部格式化程序?例如
trait Base { val id: Long }
case class ChildA(id: Long, name:String) extends Base
case class ChildB(id: Long, name:String) extends Base
case class WithTimestamp[E <: Base](base:E, timestamp:Long)
现在,如果我序列化我得到的 WithTimestamp,例如
{"base":{"id":1, "name":"foo"}, timestamp:12345 }
但我想得到的是:
{"id":1, "name":"foo", timestamp:12345 }
这似乎需要自定义序列化程序:
class WithTimestampSerializer[E <: Base] extends CustomSerializer[WithTimestamp[E]](
f => ( {
case x: JObject => ...
}, {
case x: WithTimestamp[E] =>
val j: JValue = write(x.base) // <--- not sure what to do at this point,
// i.e. write either the ChildA or ChildB default serialization
j merge JObject("timestamp" -> JLong(x.timestamp))
}))
此时我如何访问应该可用的格式化程序?
【问题讨论】:
-
我想你想使用 Extraction.decompose(x.base)。您可能可以跳过差异并将
WithTimestamp[E]替换为WithTimestamp[_]。我还会考虑更改/创建用于提供数据的模型。从长远来看可能比自定义格式化程序更简单。 -
谢谢,这很有帮助,但这仍然将我标记为需要隐式格式化程序,这似乎只是将问题推回了 1 级。添加一个隐式格式化程序会给我一个堆栈溢出,obv。创建某种循环引用。
-
哦,你需要像
implicit val formats = org.json4s.DefaultFormats + new WithTimestampSerializer这样的东西对你的序列化程序可见。或者您可以将f传递给 decompose(...)(f) 而不是使用隐式。 -
成功了,谢谢
-
@TomerShetah 我考虑过并添加了答案:)