如何使用Play Framework解析此JSON?

时间:2016-02-26 04:48:06

标签: json playframework playframework-2.0

我从Web服务返回以下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": [

          ]
        }
      }
    }
  ]
}

我试图使用Play Framework中的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(错误:列表(((0)/日期,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((0)/计数,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((0)/ ID,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((1)/日期,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((1)/计数,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((1)/ ID,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((2)/日期,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((2)/计数,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((2)/ ID,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((3)/日期,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((3)/计数,列表(ValidationError(列表(error.path.missing),WrappedArray()))),   ((3)/ ID,列表(ValidationError(列表(error.path.missing),WrappedArray())))

我试图解析JSON的方式显然有问题,但我现在花了几个小时试图找出问题并且我很好并且真的卡住了。

1 个答案:

答案 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)
    })
}