访问对象Scala中的属性

时间:2018-04-04 20:19:34

标签: json scala jackson json4s

我需要从json中获取的对象类型的示例可以在以下示例(src)中找到:

{
  "test": {
    "attra": "2017-10-12T11:17:52.971Z",
    "attrb": "2017-10-12T11:20:58.374Z"
  },
  "dummyCheck": false,
  "type": "object",
  "ruleOne": {
    "default": 2557
  },
  "ruleTwo": {
    "default": 2557
  }
}

从上面的示例中,我想访问“ruleOne”下的默认值。 我已经尝试过以下几种不同的事情,但我似乎在苦苦挣扎。我可以抓住像“dummyCheck”这样的值。关键到我需要去的地方的最佳方法是什么? 我如何尝试获取以下值的示例:

import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.DefaultFormats

implicit val formats = DefaultFormats
val test = parse(src)
println((test \ "ruleOne.default").extract[Integer])

编辑: 进一步扩展上述内容:

  def extractData(data: java.io.File) = {
    val json = parse(data)
    val result = (json \ "ruleOne" \ "default").extract[Int]
    result
  }

如果我将上述内容扩展为通过传入调用的函数:

extractData(src)

那只会给我一个RuleOne.default ..有没有一种方法可以扩展它,这样我就可以动态地传递多个字符串参数来解析(就像一个splat)

  def extractData(data: java.io.File, path: String*) = {
    val json = parse(data)
    val result = (json \ path: _*).extract[Int]
    result
  }

所以消耗它就像

extractData(src, "ruleOne", "default")

1 个答案:

答案 0 :(得分:2)

此处适用于"json4s-jackson" % "3.6.0-M2",但它应与native后端完全相同。

val src = """
  |{
  |  "test": {
  |    "attra": "2017-10-12T11:17:52.971Z",
  |    "attrb": "2017-10-12T11:20:58.374Z"
  |  },
  |  "dummyCheck": false,
  |  "type": "object",
  |  "ruleOne": {
  |    "default": 2557
  |  },
  |  "ruleTwo": {
  |    "default": 2557
  |  }
  |}""".stripMargin

import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.DefaultFormats

implicit val formats = DefaultFormats
val test = parse(src)
println((test \ "ruleOne" \ "default").extract[Int])

输出:

2557

要使其与native一起使用,只需替换

即可
import org.json4s.jackson.JsonMethods._

通过

import org.json4s.native.JsonMethods._

并确保您拥有正确的依赖关系。

修改

这是一个将字符串参数转换为路径的vararg方法:

def extract(json: JValue, path: String*): Int = {
  path.foldLeft(json)(_ \ _).extract[Int]
}

有了这个,你现在可以做到:

println(extract(test, "ruleOne", "default"))
println(extract(test, "ruleTwo", "default"))

请注意,它接受的是JValue,而不是File,因为使用File的版本会不必要地进行测试,而JValue - 版本可以使用解析了字符串常量。