Scala-如何将json作为输入参数并解析它?

时间:2019-01-12 06:34:11

标签: json scala jackson case-class

我正在编写一个小的scala练习代码,我的输入将以这种方式输入-

{
  "code": "",
  "unique ID": "",
  "count": "",
  "names": [
    {
      "Matt": {
        "name": "Matt",
        "properties": [
          "a",
          "b",
          "c"
        ],
        "fav-colour": "red"
      },
      "jack": {
        "name": "jack",
        "properties": [
          "a",
          "b"
        ],
        "fav-colour": "blue"
      }
    }
  ]
}

我将将此文件作为命令行参数传递。 我想知道如何接受输入文件来解析json并在代码中使用json键吗?

1 个答案:

答案 0 :(得分:3)

您可以使用play-json之类的json库来解析json内容。

您可以对JSON AST进行操作,也可以编写与json文件具有相同结构的case类,然后对其进行解析。

您可以找到库here的文档。


您首先必须将playjson作为依赖项添加到您的项目中。如果您使用的是sbt,只需将其添加到build.sbt文件中:

libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.13"

使用AST播放json

让我们阅读输入文件:

import play.api.libs.json.Json

object Main extends App {
  // first we'll need a inputstream of your json object
  // this should be familiar if you know java.
  val in = new FileInputStream(args(0))

  // now we'll let play-json parse it
  val json = Json.parse(in)
}

让我们从AST中提取一些字段:

val code = (json \ "code").as[String]
val uniqueID = (json \ "unique ID").as[UUID]

for {
  JsObject(nameMap) ← (json \ "names").as[Seq[JsObject]]
  (name, userMeta) ← nameMap // nameMap is a Map[String, JsValue]
} println(s"User $name has the favorite color ${(userMeta \ "fav-colour").as[String]}")

使用反序列化

正如我刚刚描述的,我们可能会创建代表您的结构的案例类:

case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, UserData]])

case class UserData(name: String, properties: Seq[String], `fav-colour`: String)

此外,您需要定义一个隐式Format,例如在每个案例类的伴随对象中。不用手工编写,可以使用为您派生它的Json.format宏:

object UserData {
  implicit val format: OFormat[UserData] = Json.format[UserData]
}

object InputFile {
  implicit val format: OFormat[InputFile] = Json.format[InputFile]
}

您现在可以反序列化json对象:

val argumentData = json.as[InputFile]

我通常更喜欢这种方法,但是在您的情况下,json结构不太适合。一种改进可以是在您的InputFile类中添加一个额外的getter,以使使用空格和名称相似的字段更容易访问:

case class InputFile(code: String, `unique ID`: UUID, count: String, names: Seq[Map[String, String]]) {
  // this method is nicer to use
  def uniqueId = `unique ID`
}