播放2.1按顺序读取JSON对象

时间:2013-09-04 06:01:32

标签: json scala playframework-2.0

JSON to Parse:http://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english

Hero Class和JSON序列化

case class Hero(
    var id:Option[Int],
    name: String,
    bio: String,
        var trueName:Option[String]
){}
implicit val modelReader: Reads[Hero] = Json.reads[Hero]

阅读数据

val future: Future[play.api.libs.ws.Response] = WS.url("http://www.dota2.com/jsfeed/heropickerdata?v=18874723138974056&l=english").get()
val json = Json.parse(Await.result(future,5 seconds).body).as[Map[String, Hero]]

var i = 1
json.foreach(p => { 
            p._2.trueName = Some(p._1)
    p._2.id = Some(i)
    p._2.commitToDatabase
    i += 1
})

我需要得到每个英雄的身份。 json中heros的顺序与他们的id匹配。显然地图是无序的,不会工作。有没有人有其他想法?

我尝试使用LinkedHashMap。我甚至试图为LinkedHashMap创建一个隐式Reads,但我失败了。如果有人认为这是答案,那么请你给我一些指导?

它只是说“找不到类型为scala.collection.mutable.LinkedHashMap [String,models.Hero]的Json反序列化器。尝试为此类型实现隐式读取或格式化。”我将特征导入到我试图读取的文件中。我有一种有趣的感觉,我的阅读中的最后一行是问题所在。我想我不能只做asInstanceOf,但我没有其他想法如何做这个读取。

LinkedHashMap隐式读取代码:http://pastebin.com/cf5NpSCX

1 个答案:

答案 0 :(得分:0)

您可以尝试直接从JsObject Json.parse直接提取数据,可能是这样的:

val json = Json.parse(Await.result(future,5 seconds).body)
val heroes: Map[String, Hero] = json match {
  case obj: JsObject => 
    obj.fields.zipWithIndex.map{ case ((name: String, heroJson: JsValue), id) =>
      heroJson.asOpt[Hero].map{ _.copy(id = Some(id)) }
    }.flatten.toMap
  case _ = > Seq.empty
}

我不相信你需要一个保留订单的地图,因为生成并修复了这个ID。