我有以下以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)',而且我敢肯定我的做法很糟糕。
答案 0 :(得分:0)
将JsDefined(null)
替换为JsDefined(JsNull)
。
您可能会感到困惑,因为println(JsDefined(JsNull))
打印为JsDefined(null)
。但这不是如何表示JSON字段的null
值。 null
表示为案例对象JsNull
。这只是一个很好的API设计,其中可能的情况用类的层次结构表示:
答案 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
做任何您想做的事情。