如何使用变换器修剪Scala Play Framework 2.1中的JsArray

时间:2013-06-06 15:51:40

标签: scala playframework-2.0 playframework-json

为了减少我无法更改的内部Web服务的Internet客户端的网络流量,我想减少JSON响应。

这是一个webservice“relay”,它只提取JSON响应的特定子集。

由于所有发生的事情都是将JSON从一种格式转换为另一种格式,我宁愿在Play Framework 2.1中使用新的JSON变换器(参见:http://www.playframework.com/documentation/2.1.1/ScalaJsonTransformers

为了增加难度,响应是一组不同的JSON对象,每个对象只需要两个字段。

作为一个特定的虚拟示例,我试图转换以下JSON:

[
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ],
    "keyC": "drop this value"
  },
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ],
    "keyD": "drop this value",
    "keyE": "drop this value"
  },
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ],
    "extraRandomKeys": "drop this value",
    "fieldsWhichMayNotAlwaysAppear: "drop this value"
  }
]

成:

[
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ]
  },
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ]
  },
  {
    "keyA": "keep this value",
    "keyB": [ {"value": "keep this value", "anotherValue": "keep this value" } ]
  }
]

我使用的模板方法是:

def relayWsResponse = Action {
  request =>
    Async {
      WS.url("http://internalhost/service")
        .get()
        .map(
        response => {
          Ok(
            response.json.transform(
              ???
            ).get
          )
        }
      )
    }
}

1 个答案:

答案 0 :(得分:3)

它有效,但可能不是最佳选择:

import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._

val transformer: Reads[JsArray] = of[JsArray].map{
  case JsArray(xs) => JsArray(xs.flatMap{
    case x: JsObject => Some(
      x.transform(
        (__ \ "keyA").json.pickBranch and (__ \ "keyB").json.pickBranch reduce
      ).get
    )
  })
}