在 Scala Play 框架中将 json 数组转换为模型 class 的 Seq
Convert json array to Seq of model class in Scala Play framework
我正在使用 Scala Play 框架和 Instagram API,我想提取一个 json 数组到我的模型 class 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 对象映射到模型 class,但是如何将 json 数组映射到 Seq/List/Array 用户?
我找到的解决方案如下:
val users: Seq[User] = (json \ "data").as[JsArray].value.map(j => j.validate[User].get)
可能存在更漂亮的方法,但在其他答案之前我会坚持使用这个方法。
Json 初始代码非常棒,它是我反序列化 json 的首选方式。您将必须修改您的用户 class 以适应 instagram 模型 API。或者,您可以制作一个 class 之类的 InstagramApiUser
或其他东西来进行反序列化,如果您认为这对您的流程更好,则稍后复制到您自己的 class 。这是代码,它在 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]
然后您可以记录错误以及解析您的原因Json失败。
如果您不喜欢命名您的案例 class 成员以匹配 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 _)
}
其他方面都是一样的。
我正在使用 Scala Play 框架和 Instagram API,我想提取一个 json 数组到我的模型 class 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 对象映射到模型 class,但是如何将 json 数组映射到 Seq/List/Array 用户?
我找到的解决方案如下:
val users: Seq[User] = (json \ "data").as[JsArray].value.map(j => j.validate[User].get)
可能存在更漂亮的方法,但在其他答案之前我会坚持使用这个方法。
Json 初始代码非常棒,它是我反序列化 json 的首选方式。您将必须修改您的用户 class 以适应 instagram 模型 API。或者,您可以制作一个 class 之类的 InstagramApiUser
或其他东西来进行反序列化,如果您认为这对您的流程更好,则稍后复制到您自己的 class 。这是代码,它在 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]
然后您可以记录错误以及解析您的原因Json失败。
如果您不喜欢命名您的案例 class 成员以匹配 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 _)
}
其他方面都是一样的。