Scala将JSON反序列化为Collection

时间:2018-07-02 06:45:32

标签: scala scala-collections

我的JSON文件包含以下详细信息 { “类别”:“年龄,性别,邮政编码” }

我的Scala代码低于一个

val filename = args.head
println(s"Reading ${args.head} ...")
val json = Source.fromFile(filename)
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val parsedJson = mapper.readValue[Map[String, Any]](json.reader())   
val data = parsedJson.get("category").toSeq

它返回Seq(Any)=示例List(年龄,性别,邮政编码),但我需要Seq(String)输出,如果对此有任何想法,请帮助我。

3 个答案:

答案 0 :(得分:1)

scala中的想法是,尽可能使用Map[String, Any]放弃类型安全。

因此,我建议使用代表您的JSON数据的数据类。

示例

定义映射器,

scala> import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper

scala> import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

scala> import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.DefaultScalaModule

scala> val mapper = new ObjectMapper() with ScalaObjectMapper
mapper: com.fasterxml.jackson.databind.ObjectMapper with com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper = $anon$1@d486a4d

scala> mapper.registerModule(DefaultScalaModule)
res0: com.fasterxml.jackson.databind.ObjectMapper = $anon$1@d486a4d

现在,当您反序列化为Map[K, V]时,无法指定所有嵌套的数据结构,

scala> val jsonString = """{"category": ["metal", "metalcore"], "age": 10, "gender": "M", "postCode": "98109"}"""
jsonString: String = {"category": ["metal", "metalcore"], "age": 10, "gender": "M", "postCode": "98109"}

scala> mapper.readValue[Map[String, Any]](jsonString)
res2: Map[String,Any] = Map(category -> List(metal, metalcore), age -> 10, gender -> M, postCode -> 98109)

以下是一种为所需的数据结构投射一些键的解决方案,但我个人不建议这样做。

scala> mapper.readValue[Map[String, Any]](jsonString).get("category").map(_.asInstanceOf[List[String]]).getOrElse(List.empty[String])
res3: List[String] = List(metal, metalcore)

最好的解决方案是定义一个数据类,在下面的示例中,我将其称为SomeData并将其反序列化。 SomeData是根据您的JSON数据结构定义的。

scala> final case class SomeData(category: List[String], age: Int, gender: String, postCode: String)
defined class SomeData

scala> mapper.readValue[SomeData](jsonString)
res4: SomeData = SomeData(List(metal, metalcore),10,M,98109)

scala> mapper.readValue[SomeData](jsonString).category
res5: List[String] = List(metal, metalcore)

答案 1 :(得分:0)

只需将JSON作为JsonNode读取,并直接访问该属性:

val jsonNode = objectMapper.readTree(json.reader())
val parsedJson = jsonNode.get("category").asText

答案 2 :(得分:0)

  • 通过使用scala泛型函数将JSON字符串转换为Case类/对象,您可以反序列化为所需的任何内容。像

    • JSON to Collection
    • JSON to Case Class
    • JSON to Case Class with Object as field
  • 请找到我使用泛型here提供的有效且详细的答案。