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/