Scala播放JSON,查找并匹配包含空值的定义字段

时间:2018-11-23 12:05:02

标签: json scala playframework play-json

我有以下以JsObject返回的Json块

{
  "first_block": [
    {
      "name": "demo",
      "description": "first demo description"
    }
  ],
  "second_block": [
    {
      "name": "second_demo",
      "description": "second demo description",
      "nested_second": [
        {
          "name": "bob",
          "value": null
        },
        {
          "name": "john",
          "value": null
        }
      ]
    }
  ]
}

由此,我想返回第二个块(名称和值的嵌套数组)中可能具有的所有可能值的列表。所以上面的例子 List([bob,null],[john,null])或类似的内容。

我遇到的问题是值部分了解空值。我试图匹配它并返回一个字符串"null",但是我无法使其与Null值匹配。

对我来说,最好的方法是返回nested_second数组中的名称和值。

我曾经尝试过使用case类和readAsNullable,但运气不佳,而我最近的尝试是遵循以下原则:

val secondBlock = (jsObj \ "second_block").as[List[JsValue]]

secondBlock.foreach(nested_block => {
  val nestedBlock = (nested_block \ "nested_second").as[List[JsValue]]
  nestedBlock.foreach(value => {
    val name = (value \ "name").as[String] //always a string
    var convertedValue = ""
    val replacement_value = value \ "value"
    replacement_value match {
      case JsDefined(null) => convertedValue = "null"
      case _ => convertedValue = replacement_value.as[String]
    }

    println(name)
    println(convertedValue)
  })
}
)

无论如何,convertedValue似乎都返回'JsDefined(null)',而且我敢肯定我的做法很糟糕。

2 个答案:

答案 0 :(得分:0)

JsDefined(null)替换为JsDefined(JsNull)

您可能会感到困惑,因为println(JsDefined(JsNull))打印为JsDefined(null)。但这不是如何表示JSON字段的null值。 null表示为案例对象JsNull。这只是一个很好的API设计,其中可能的情况用类的层次结构表示:

enter image description here

答案 1 :(得分:0)

对于play-json,我总是使用case-classes

我从本质上简化了您的问题:

import play.api.libs.json._

val jsonStr = """[
        {
          "name": "bob",
          "value": null
        },
        {
          "name": "john",
          "value": "aValue"
        },
        {
          "name": "john",
          "value": null
        }
      ]"""

定义案例类

case class Element(name: String, value: Option[String])

在伴随object中添加格式器:

object Element {
  implicit val jsonFormat: Format[Element] = Json.format[Element]
}

使用validate

Json.parse(jsonStr).validate[Seq[Element]] match {
  case JsSuccess(elems, _) => println(elems)
  case other => println(s"Handle exception $other")
}

这将返回:List(Element(bob,None), Element(john,Some(aValue)), Element(john,None))

现在,您可以使用values做任何您想做的事情。