使用 Play-JSON 库解析对象序列
Posted
技术标签:
【中文标题】使用 Play-JSON 库解析对象序列【英文标题】:Parsing an object-sequence with Play-JSON library 【发布时间】:2017-07-21 14:27:50 【问题描述】:作为免责声明:我对 Scala 和一般的函数式编程非常陌生。
我有以下课程:
case class A(
field1: String,
field2: DateTime
)
case class B(
listOfStuff: Seq[A]
)
object A
def create(field1: String, field2: DateTime): A = A(field1, field2)
object B
def create(listOfStuff: Seq[A]): B = B(listOfStuff)
(存在create()
函数是因为我在使用apply()
时有时会在我的代码中遇到问题。让我们忽略这一点,我怀疑它是否相关。)
我以 JSON 格式获取这些对象,并尝试使用 Play-JSON 库解析它们。一个重要方面是 JSON 文本中可能缺少列表 (Seq
),它是一个可选字段。
考虑到这一点,这就是我写那一行的方式:
private implicit val messageReader = (
//...
(__ \ "stuff").readNullable[Seq[A]].map(_.getOrElse(Seq()))
//...
)(B.create _)
编译时出现如下错误:
错误:(!line!, !column!) 找不到类型 Seq[A] 的 Json 反序列化器。 尝试为此类型实现隐式读取或格式化。
根据我在this question 中看到的内容,显然您需要为每种类型的Reads[T]
提供一个implicit
实例T
,这不是语言的一部分(或类似的东西,我是否提到过我'我是新手?)
所以我还在同一范围内添加了辅助Reads[T]
,我的代码现在看起来像这样:
private implicit val messageReader = (
(__ \ "stuff").readNullable[Seq[A]].map(_.getOrElse(Seq()))
)(B.create _)
private implicit val anotherReader = (
(__ \ "field1").read[String] and
(__ \ "field2").read[String].map(org.joda.time.DateTime.parse)
)(A.create _)
但是我仍然在同一行上遇到同样的错误。
我觉得这里有一些非常简单和明显的问题,但我无法弄清楚它是什么。
我该如何解决这个问题?
【问题讨论】:
为了能够使用Seq[T]
的解析器,T
的解析器必须可用
@cchantep 这就是我添加private implicit val anotherReader
的原因。还是不行。
它必须在 before 之前可用(而不是作为后来的 val)
@cchantep 你的建议奏效了。我只是颠倒了他们的顺序,一切都很好。将其发布为答案,我会接受它;)。
【参考方案1】:
如果B.create
接受单个参数,那么它的读取可能如下所示:
private implicit val messageReader : Reads[B] =
(__ \ "stuff").readNullable[Seq[A]].map(_.getOrElse(Seq())).map(B.create)
【讨论】:
实际上它们大约有 20 个字段,但我当然出于这个问题的目的删除了它们。以上是关于使用 Play-JSON 库解析对象序列的主要内容,如果未能解决你的问题,请参考以下文章