2

我使用implicit val reads到JSON映射,如:斯卡拉发挥读取解析嵌套的JSON

{ 
    "id": 1 
    "friends": [ 
    { 
     "id": 1, 
     "since": ... 
    }, 
    { 
     "id": 2, 
     "since": ... 
    }, 
    { 
     "id": 3, 
     "since": ... 
    } 
    ] 
} 

的情况下,类

case class Response(id: Long, friend_ids: Seq[Long]) 

我只能使其与反映了一个中间类工作JSON friends结构。但我从不在我的应用中使用它。有没有办法编写一个Reads[Response]对象,以便我的Response类直接映射到给定的JSON?

+0

'case class Response(id:Long,friends:Seq [Friend])''? – mfirry

+0

这将工作,但我没有,也不想创建“朋友”类。我只需要他们的ID –

回答

3

你只需要简单的读取[回应]有明确Reads.seq()friend_ids

val r: Reads[Response] = (
    (__ \ "id").read[Long] and 
    (__ \ "friends").read[Seq[Long]](Reads.seq((__ \ "id").read[Long])) 
)(Response.apply _) 

和结果将是:

r.reads(json) 

scala> res2: play.api.libs.json.JsResult[Response] = JsSuccess(Response(1,List(1, 2, 3)),) 
1

你可以尝试以下

@annotation.tailrec 
def go(json: Seq[JsValue], parsed: Seq[Long]): JsResult[Seq[Long]] = 
    json.headOption match { 
    case Some(o @ JsObject(_)) => (o \ "id").validate[Long] match { 
     case JsError(cause) => JsError(cause) 
     case JsSuccess(id) => go(json.tail, parsed :+ id) 
    } 
    case Some(js) => JsError(s"invalid friend JSON (expected JsObject): $js") 
    case _ => JsSuccess(parsed) // nothing more to read (success) 
    } 

implicit val friendIdReader = Reads[Seq[Long]] { 
    case JsArray(values) => go(values, Nil) 
    case json => JsError(s"unexpected JSON: $json") 
} 

implicit val responseReader = Json.reads[Response] 
// responseReader will use friendIdReader as Reads[Seq[Long]], 
// for the property friend_ids 
+0

感谢您的建议!这可能会起作用,但如果没有更简单的方法,我宁愿选择实用类(例如'Friend')。我想没有。 –

1

最简单的方法可能是:

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


case class Response(id: Long, friend_ids: Seq[Friends]) 

object Response { 

    implicit val userReads: Reads[Response] = (
    (JsPath \ "id").read[Long] and 
     (JsPath \ "friends").read[Seq[Friends]] 
    ) (Response.apply _) 
} 

case class Friends(id: Long, since: String) 
object Friends { 
    implicit val fmt = Json.format[Friends] 
} 

没有case class Friends我发现很难找到一个解决方案,但会后,如果我能找到一个

编辑︰添加链接回答斯卡拉reedit

所以,我想了解更多关于如何解析json到模型,并决定问Reedit。收到一些很酷的链接,来看看:

https://www.reddit.com/r/scala/comments/4bz89a/how_to_correctly_parse_json_to_scala_case_class/