使用Reads [T]时丢弃包装数据

时间:2013-09-30 04:48:29

标签: json scala playframework

我认为我想做的事应该相对简单,但我不确定。我正在进行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
)

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

1 个答案:

答案 0 :(得分: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 macro inception游戏。您的示例的代码可以写成如下:

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

如您所见,case类val必须与其Json计数器部分具有相同的名称。另外,我使用的是格式而不是读取,这当然取决于你,但大多数时候你需要读取和写入,这是格式给你的。