将json数组转换为Scala Play框架中模型类的Seq

时间:2015-08-27 12:24:35

标签: json scala playframework playframework-2.0

我正在使用Scala Play框架和Instagram API,我想将json数组提取到我的模型类User

case class User(val userId: String, val username: String, val profilePhoto: String, val name: String)

API中的json数组示例如下:

{
  "pagination":  {},
  "meta":  {},
  "data":  [
     {
      "username": "carolinabentocb",
      "profile_picture": "https://igcdn-photos-f-a.akamaihd.net/hphotos-ak-xfa1/t51.2885-19/s150x150/11429783_1673078532912085_1496721162_a.jpg",
      "id": "363753337",
      "full_name": "Carolina Bento"
    },
     {
      "username": "pereira3044",
      "profile_picture": "https://igcdn-photos-e-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-19/s150x150/11351764_1662987433917180_971708049_a.jpg",
      "id": "2141448590",
      "full_name": "Alex"
    }
]
}

this link中解释了如何将json对象映射到模型类,但是如何将json数组映射到Seq / List / Array of Users?

2 个答案:

答案 0 :(得分:2)

我找到的解决方案如下:

<%=example%>

它可能存在更美妙的方法,但我会坚持使用这个方法,直到其他答案。

答案 1 :(得分:2)

Json初始代码非常棒,它是我反序列化json的首选方法。您必须修改User类以适合instagram模型API。或者,您可以创建一个类似InstagramApiUser的案例类或其他东西来进行反序列化,如果您认为对您的流程更好,则可以将其复制到您自己的类中。这是代码,它在scala repl中工作。

import play.api.libs.json.{Json, Format}


val js = Json.parse("""{
  "pagination":  {},
  "meta":  {},
  "data":  [
     {
      "username": "carolinabentocb",
      "profile_picture": "https://igcdn-photos-f-a.akamaihd.net/hphotos-ak-xfa1/t51.2885-19/s150x150/11429783_1673078532912085_1496721162_a.jpg",
      "id": "363753337",
      "full_name": "Carolina Bento"
    },
     {
      "username": "pereira3044",
      "profile_picture": "https://igcdn-photos-e-a.akamaihd.net/hphotos-ak-xaf1/t51.2885-19/s150x150/11351764_1662987433917180_971708049_a.jpg",
      "id": "2141448590",
      "full_name": "Alex"
    }
  ]
}""")

case class User(id: String, username: String, profile_picture: String, full_name: String)
object User {
  implicit val jsonFormat: Format[User] = Json.format[User]
}

val result = (js \ "data").as[Seq[User]]

在Play Json库中有三种方法可以反序列化Json,而as在我看来是最不惯用的方法,因为如果它无法解析就抛出异常。您可以尝试使用asOpt[A]生成Option[A]或更好validate[A],这将生成JsResult[A],然后您可以记录错误以及解析您的原因杰森失败了。

如果您不喜欢命名您的案例类成员以匹配API名称,您可以手动编写Reads

import play.api.libs.json.{Json, Reads, JsPath}
import play.api.libs.functional.syntax._

case class User(val userId: String, val username: String, val profilePhoto: String, val name: String)
object User {
  implicit val jsonReads: Reads[User] = (
    (JsPath \ "id").read[String] and
    (JsPath \ "username").read[String] and 
    (JsPath \ "profile_picture").read[String] and
    (JsPath \ "full_name").read[String]
  )(User.apply _)
}

否则它的工作方式相同。