使用Play Json转换json时如何忽略不存在的键

时间:2015-04-10 10:59:35

标签: json scala playframework

以下代码导致例外,例如json中不存在source.foo密钥。 java.util.NoSuchElementException: JsError.get

我正在尝试使用动态选择的Reads序列来转换json(我称之为变换器)。

如何忽略不存在的字段?即,不要在转换后的json中为源json中不存在的键写任何内容?

  val iconTransformer = (__ \ 'res \ 'foo).json.copyFrom ((__ \ 'source \ 'foo).json.pick)

  val ppTransformer = (__ \ 'res \ 'bar).json.copyFrom((__ \ 'source \ 'bar).json.pick)

  val transformers = Seq(iconTransformer, ppTransformer)

  val combined = transformers.reduce((a, b) => (a and b).reduce)

  json.transform(combined)

2 个答案:

答案 0 :(得分:0)

您可以创建一个阅读器,然后使用validate来确保元素实际存在:

val json = { ... }

val nameReads: Reads[String] = (JsPath \ "name").read[String]

val nameResult: JsResult[String] = json.validate[String](nameReads)

nameResult match {
  case s: JsSuccess[String] => println("Name: " + s.get)
  case e: JsError => println("Errors: " + JsError.toFlatJson(e).toString()) 
}

查看documentation,特别是"使用读取验证"。

答案 1 :(得分:0)

我还没有测试过,但是这里有一种方法,为了清晰起见,有点冗长:

  object iconTransformer extends Reads[JsObject] {
    def reads(json: JsValue): JsResult[JsValue] =
      (json \  "source" \ "foo") match {
        case _:JsUndefined => JsSuccess(json)
        case jsValue:JsValue =>
          json.transform((__ \ 'res \ 'foo).json.put(jsValue))
    }
  }

它非常丑陋,但是很容易将丑陋的位封装起来以便重用。 我希望有一种更简单的方式 - 我只是不知道。