2

ayrıştırmak okur:scala oyun iç içe JSON ben gibi Json haritaya <code>implicit val reads</code> kullanıyorum

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

bir olgu sınıfına

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

Ben sadece yansıtan bir ara sınıf ile çalışmak yapabilirsiniz JSON friends yapısı. Ancak bunu asla uygulamamda kullanmıyorum. Reads[Response] nesnesini yazmanın bir yolu var, böylece Response sınıfım doğrudan verilen JSON ile eşleşecek mi?

+0

'case class Response gibi bir şey (id: Uzun, arkadaş: Seq [Arkadaş])'? Çalışacak olan – mfirry

+0

, ama 'Friend' sınıfı oluşturmak istemiyorum ve istemiyorum. Sadece onların kimliklerine ihtiyacım var –

cevap

3

Yalnızca basit [Yanıtı] Okunanlar gerek açık Reads.seq() şurada friend_ids böyle

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

olarak ve sonuç olacaktır:

r.reads(json) 

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

Olabilirsin aşağıdaki

@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

Öneriniz için teşekkürler! Muhtemelen işe yarayacak, ancak daha kolay bir yol bulunmuyorsa, bir yardımcı program sınıfı (örn. 'Friend') ile gitmeyi tercih ederim. Ve sanırım hiç yok. –

1

kolay yolu deneyebilirsiniz: case class Friends olmadan

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] 
} 

Bir çözüm bulmak için daha bulma yaşıyorum ama bir bulabilirse yayınlayacağız

Düzenleme: Scala cevap için bağlantı eklendi yeniden düzenlemek

Json'un modellere nasıl ayrılacağı hakkında biraz daha fazla bilgi edinmek istedim ve Reedit'i sormaya karar verdim. bir göz, bazı hoş serin bağlantılar Alınan:

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

İlgili konular