2016-02-26 47 views
0

我從一個web服務返回以下JSON:如何使用Play框架解析此JSON?

{ 
    "hits": [ 
    { 
     "created_at": "2016-02-01T15:01:03.000Z", 
     "title": "title", 
     "num_comments": 778, 
     "parent_id": null, 
     "_tags": [ 
     "story", 
     "author", 
     "story_11012044" 
     ], 
     "objectID": "11012044", 
     "_highlightResult": { 
     "title": { 
      "value": "title", 
      "matchLevel": "full", 
      "matchedWords": [ 
      "title" 
      ] 
     }, 
     "author": { 
      "value": "author", 
      "matchLevel": "none", 
      "matchedWords": [ 

      ] 
     }, 
     "story_text": { 
      "value": "Please lead", 
      "matchLevel": "none", 
      "matchedWords": [ 

      ] 
     } 
     } 
    } 
    ] 
} 

,我試圖在遊戲框架使用JSON解析庫解析它。我有以下代碼:

import play.api.libs.functional.syntax._ 
import play.api.libs.json._ 
case class Post(id: Long, date: String, count: Int) 
object Post { 

    implicit val postFormat = Json.format[Post] 
    implicit val writes: Writes[Post] = (
    (JsPath \ "id").write[Long] and 
    (JsPath \"date").write[String] and 
    (JsPath \ "count").write[Int] 
)(unlift(Post.unapply)) 

    implicit val reads: Reads[Post] = (
    (JsPath \ "objectID").read[Long] and 
    (JsPath \ "created_at").read[String] and 
    (JsPath \ "num_comments").read[Int] 
)(Post.apply _) 
} 

import play.api.libs.json._ 
class PostRepo { 
    val request: WSRequest = ws.url(MY_URL) 

    def getPosts: Future[Seq[Post]] = 
    val result: Future[JsValue] = request.get().map(response => 
     response.status match { 
      case 200 => Json.parse(response.body) 
      case _ => throw new Exception("Web service call failed: " + response.body) 
    }) 
    result.map({ 
     jsonvalue => println("JSARRAY: " + jsonvalue); 
     (jsonvalue \ "hits").as[Seq[Post]] 
    }) 
    result 
} 

現在,當我運行代碼,我收到以下錯誤:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[JsResultException: 

JsResultException(errors:List(((0)/date,List(ValidationError(List(error.path.missing),WrappedArray()))), ((0)/count,List(ValidationError(List(error.path.missing),WrappedArray()))), ((0)/id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((1)/date,List(ValidationError(List(error.path.missing),WrappedArray()))), ((1)/count,List(ValidationError(List(error.path.missing),WrappedArray()))), ((1)/id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((2)/date,List(ValidationError(List(error.path.missing),WrappedArray()))), ((2)/count,List(ValidationError(List(error.path.missing),WrappedArray()))), ((2)/id,List(ValidationError(List(error.path.missing),WrappedArray()))), ((3)/date,List(ValidationError(List(error.path.missing),WrappedArray()))), ((3)/count,List(ValidationError(List(error.path.missing),WrappedArray()))), ((3)/id,List(ValidationError(List(error.path.missing),WrappedArray())))

顯然東西是錯誤的我試圖解析JSON的方式但我現在花了幾個小時試圖弄清楚這個問題,並且我很好並且堅持不懈。

+0

錯誤一些重構代碼顯示沒有從(__ \「命中」) –

回答

0

Reads.seq

val r = (__ \ "hits").read[Seq[Post]](Reads.seq[Post]) 

def getPosts: Future[Seq[Post]] = { 
    WS.url(MY_URL).get().map(response => 
    response.status match { 
     case 200 => r.reads(response.json) match { 
     case JsError(e) => throw new Exception("Json read fails. Response body:" + response.json.toString() + "\nRead error:" + e.toString()) 
     case JsSuccess(x, _) => x 
     } 
     case _ => throw new Exception("Web service call failed: " + response.body) 
    }) 
} 
+0

嗯,這並不編譯或解決問題 – jcm

+0

重構代碼,正確讀錯字從'root'帖子。在你的閱讀器'objectID'中讀取的時間長,但在json中保存爲字符串:JsError(List((/ hits(0)/ objectID,List(ValidationError(List(error.expected.jsnumber),WrappedArray()))) ))。 'r'讀取您的json爲 scala> res3:play.api.libs.json.JsResult [Seq [Post]] = JsSuccess(List(Post(11012044,2016-02-01T15:01:03.000Z, 778)),/打)。所以沒有錯誤 –

+0

好吧,我已經添加了你的代碼,但我得到了「Json讀取失敗」JsError的值是:List((/ hit(0)/ date,List(ValidationError(List(error.path ()。),(/ hits(0)/ id,List(ValidationError(List(error.path.missing),WrappedArray()))), (ValidationError(List(error.path.missing),WrappedArray())))) – jcm