Scala play JSON, 查找并匹配定义字段保持空值

Scala play JSON, lookup and match defined field holding null value

我有以下 Json 块,我已将其 return 编辑为 JsObject

{
  "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
        }
      ]
    }
  ]
}

据此,我想 return 我可以在第二个块中拥有的所有可能值的列表,名称和值的嵌套数组。所以上面的例子 List([bob,null],[john,null]) 或类似的东西。

我遇到的问题是值部分理解空值。我试图匹配它和 return 一个字符串 "null" 但我无法让它匹配 Null 值。

我 return 返回 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 return 和 'JsDefined(null)' 一样,我确信我这样做的方式非常糟糕。

JsDefined(null) 替换为 JsDefined(JsNull)

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

的层次结构表示

使用 play-json 我总是使用 case-classes!

我把你的问题简化到了本质:

import play.api.libs.json._

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

定义案例class

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")
}

这个returns:List(Element(bob,None), Element(john,Some(aValue)), Element(john,None))

现在你可以用values做任何你想做的事了。