1

我认为我正在尝试做的事情应该相对简单,但我不确定。我正在进行 API 调用以获取应用程序列表,我想将它们读出。但是,该列表嵌套在响应中。响应类似于:

{
  "response": {
    "instances": [
      { /* object I'm concerned with reading */ },
      ...
    ]
  }
}

我有一个读者目前定义为:

implicit val appReader : Reads[App] = (
  (__ \ "ip_address").read[String] and
  (__ \ "hostname").read[String] and
  (__ \ "application_version").read[String]
)(App)

和一类:

case class App(
    ip: String,
    hostname: String,
    version: String
)

但是,我不确定如何获取数据,因为它隐藏在响应中,或者是否有一种方法可以丢弃该数据。

4

1 回答 1

2

我假设应用程序位于实例数组中,如下所示:

val js = Json.parse("""
           {
             "response": {
               "instances": [
                 { "ip_address": "192.168.1.1", "hostname": "host1", "application_version": "1.0"},
                 { "ip_address": "192.168.1.2", "hostname": "host2", "application_version": "1.0"}
               ]
             }
           }
           """)

现在,读取定义为 App 的应用程序列表:

val responseRead =
  (__ \ "response").read(
    (__ \ "instances").read[List[App]])

val apps = responseRead.reads(js).get

这为您提供了应用程序列表,而忽略了其余部分。如果数据结构与假设的有所不同,这应该为您指明正确的方向。

编辑:大多数时候我更喜欢使用Json 宏开始播放。您的示例的代码可以编写如下:

case class App(
  ip_address: String,
  hostname: String,
  application_version: String)

object App {
  implicit val appFormat = Json.format[App]
}

case class Response(
  instances: List[App])

object Response {
  implicit val responseFormat = Json.format[Response]
}

case class Root(
  response: Response)

object Root {
  implicit val rootFormat = Json.format[Root]
}

val root = js.as[Root]
val apps = root.response.instances

如您所见,案例类 val 必须与其 Json 对应部分具有相同的名称。此外,我使用格式而不是读取,这当然取决于您,但大多数时候您需要读取和写入,这正是格式为您提供的。

于 2013-09-30T06:20:21.543 回答