使用play scala解析json集合

时间:2015-11-27 10:49:00

标签: json scala playframework

假设我有一个案例类:

case class Element(name: String)

和一个具有读取的伴侣类:

object Element {
  implicit val elementReads = (
    (JsPath / "name").read[String]
  )
}

我需要这个对象的地图,所以:

object ElementMap {
  def apply(elements: Iterable[Element]) = {
    val builder = Map.newBuilder[String, Element]
    elements.foreach { x => builder += ((x.name, x)) }
    builder result       
  }
}

最后,我必须创建一个可以从JSON读取的读取:

implicit val elementMapReads = (
    (JsPath \ "elements").read[Seq[Element]]
)(ElementMap(_))

但是我收到一条错误消息:

overloaded method value read with alternatives: (t: Seq[Element])play.api.libs.json.Reads[Seq[Element]] <and> (implicit r: play.api.libs.json.Reads[Seq[Element]])play.api.libs.json.Reads[Seq[Element]] cannot be applied to (Iterable[Element] ⇒ Map[String,Element])

1 个答案:

答案 0 :(得分:2)

这是一个有效的版本:

case class Element(name: String)

object Element {
  implicit val elementReads: Reads[Element] =
    (JsPath \ "name").read[String].map(Element.apply)

  implicit val elementMapReads: Reads[Map[String, Element]] = 
    (JsPath \ "elements").read[Seq[Element]].map(ElementMap(_))
}

object ElementMap {
  def apply(elements: Iterable[Element]) = {
    val builder = Map.newBuilder[String, Element]
    elements.foreach { x => builder += ((x.name, x)) }
    builder result       
  }
}

在您的代码中,elementReads隐含的Reads[String]Reads[Element],而不是Reads[_];一般来说,在play-json中使用显式类型注释会更好,因为有一些需要它们的隐式转换。

此外,Reads[Seq[Element]]有一个map方法,当你有单字段包装器时很方便,并且还解决了转换Reads[Map[String, Element]]以创建elementMapReads的问题。

最后,移动Element随播广告中的container应该使其自动可用(即使用时不需要导入);我没有测试它,但据我所知,它应该可以工作。