2017-12-19 2 views
0

Ich versuche, einen verschachtelten Wert von einem JSON-Inhalt zu erhalten, den ich von einem API Rest (Swagger) bekomme. Ich möchte mit dem ersten "url" Wert zuzugreifen:Scala Play Json JSResultException Fehler API

val getFeedVersionURL = url("https://api.transitfeeds.com/v1/getFeedVersions?").GET <<? List(
    "key" -> someKey, 
    "feed" -> "consorcio-regional-de-transportes-de-madrid/743", 
    "page" -> "1", 
    "limit" -> "10000", 
    "err" -> "1 (default)", 
    "warn" ->"1 (default)") 

    val response : Future[String] = Http.configure(_ setFollowRedirects true)(getFeedVersionURL OK as.String) 

    val src: String = getFeedVersionURL.toString() 

    response onComplete { 
    case Success(content) => { 
     println("Successful response" + content) 

     //Parse the content 
     val jsonObject = Json.parse(content) 
     //Get url value 
     val fileDownloadURL = (jsonObject \ "results" \ "versions" \ "url").as[String] 
     //Save the file 
     new URL(fileDownloadURL) #> new File("C:/Users//Desktop//file.zip") !! 


    } 
    case Failure(t) => { 
     println("An error has occured: " + t.getMessage) 
    } 
    } 

Dies ist die json Ich erhalte:

{ 
    "status": "OK", 
    "ts": 1513600944, 
    "results": { 
    "total": 4, 
    "limit": 100, 
    "page": 1, 
    "numPages": 1, 
    "versions": [ 
     { 
     "id": "consorcio-regional-de-transportes-de-madrid/743/20171127", 
     "f": { 
      "id": "consorcio-regional-de-transportes-de-madrid/743", 
      "ty": "gtfs", 
      "t": "Metro Ligero de Madrid GTFS", 
      "l": { 
      "id": 167, 
      "pid": 166, 
      "t": "Madrid, Spain", 
      "n": "Madrid", 
      "lat": 40.416775, 
      "lng": -3.70379 
      }, 
      "u": { 
      "i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196" 
      } 
     }, 
     "ts": 1511848526, 
     "size": 403388, 
     "url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20171127/download", 
     "d": { 
      "s": "20170106", 
      "f": "20180629" 
     }, 
     "err": [], 
     "warn": [] 
     }, 
     { 
     "id": "consorcio-regional-de-transportes-de-madrid/743/20170927", 
     "f": { 
      "id": "consorcio-regional-de-transportes-de-madrid/743", 
      "ty": "gtfs", 
      "t": "Metro Ligero de Madrid GTFS", 
      "l": { 
      "id": 167, 
      "pid": 166, 
      "t": "Madrid, Spain", 
      "n": "Madrid", 
      "lat": 40.416775, 
      "lng": -3.70379 
      }, 
      "u": { 
      "i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196" 
      } 
     }, 
     "ts": 1506554131, 
     "size": 403052, 
     "url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20170927/download", 
     "d": { 
      "s": "20170106", 
      "f": "20180925" 
     }, 
     "err": [], 
     "warn": [] 
     }, 
     { 
     "id": "consorcio-regional-de-transportes-de-madrid/743/20170526", 
     "f": { 
      "id": "consorcio-regional-de-transportes-de-madrid/743", 
      "ty": "gtfs", 
      "t": "Metro Ligero de Madrid GTFS", 
      "l": { 
      "id": 167, 
      "pid": 166, 
      "t": "Madrid, Spain", 
      "n": "Madrid", 
      "lat": 40.416775, 
      "lng": -3.70379 
      }, 
      "u": { 
      "i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196" 
      } 
     }, 
     "ts": 1495816290, 
     "size": 408985, 
     "url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20170526/download", 
     "d": { 
      "s": "20170106", 
      "f": "20180526" 
     }, 
     "err": [], 
     "warn": [] 
     }, 
     { 
     "id": "consorcio-regional-de-transportes-de-madrid/743/20161012", 
     "f": { 
      "id": "consorcio-regional-de-transportes-de-madrid/743", 
      "ty": "gtfs", 
      "t": "Metro Ligero de Madrid GTFS", 
      "l": { 
      "id": 167, 
      "pid": 166, 
      "t": "Madrid, Spain", 
      "n": "Madrid", 
      "lat": 40.416775, 
      "lng": -3.70379 
      }, 
      "u": { 
      "i": "http://crtm.maps.arcgis.com/home/item.html?id=aaed26cc0ff64b0c947ac0bc3e033196" 
      } 
     }, 
     "ts": 1476308287, 
     "size": 420670, 
     "url": "https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20161012/download", 
     "d": { 
      "s": "20160101", 
      "f": "20170621" 
     }, 
     "err": [], 
     "warn": [] 
     } 
    ] 
    } 
} 

Das Problem ist ich erhalten diese Fehlermeldung:

play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(error.expected.jsstring,WrappedArray()))))) 

Irgendwelche Ideen ?

+0

'„Versionen“\„url“' erwarten 'versions' zu benutzen, ein Objekt zu sein, während es ein Array – cchantep

Antwort

1

cchanstep im Kommentar ist korrekt. Sie müssen den Schlüssel versions herausziehen und entsprechend damit umgehen. Hier einige Sehr grobe Code, der tut, was Sie wollen:

import play.api.libs.json._ 
val jsonObject = Json.parse(s) // s is that string you gave in your q 

val fileDownloadURL: String = (jsonObject \ "results" \ "versions") match { 
    case JsDefined(JsArray(versions)) => versions.headOption match { 
     case Some(jsValue) => (jsValue \ "url").as[String] 
     case _ => "NOPE hope you got some logic here" 
    } 
    case nope => throw new IllegalArgumentException("handle this better than this!") 
} 

Und ich bekomme:

res0: String = https://transitfeeds.com/p/consorcio-regional-de-transportes-de-madrid/743/20171127/download 

Beachten Sie, dass ich tat dies 2.4 in meiner Konsole spielen mit, und für 2.3 und anderen Versionen gibt können Unterschiede sein. Wenn Sie die Spielversion bereitstellen, die Sie verwenden, kann ich Ihnen wahrscheinlich ein paar grobe Ideen geben, wie Sie das erreichen können, was Sie vorhaben.

Beachten Sie, dass die oben mit dem passenden einer Art und Weise ist, wäre eine andere Art und Weise as ein Haufen

val thisToo = (jsonObject \ "results" \ "versions").as[JsArray].value.headOption.map(first => (first \ "url").as[String]).getOrElse(throw new IllegalArgumentException("handle this better than this!")) 
+0

Vielen Dank Kumpel, Ihr Code ist fantastisch und funktioniert. Aber was, wenn ich alle 'URL'-Felder dieses jsons in einer Variablen (Liste) speichern muss? Ich habe mit bucle versucht, funktioniert aber nicht. –

+0

Für alle URLs könnten Sie '.as [JsArray] .value.headOption.map (erste => (erste" url "). As [String])' zu '.as [JsArray] .value.map (erste => (erste "url"). als [String]) ' – EdgeCaseBerg