Scala 反序列化 JSON 到 Collection
Scala deserialize JSON to Collection
我的 JSON 文件包含以下详细信息
{
"category":"age, gender,post_code"
}
我的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) = example List(age, gender,post_code) 但我需要 Seq(String) 输出如果有人对此有任何想法请帮助我。
scala 中的想法是尽可能实现类型安全,而您使用 Map[String, Any]
放弃了这一点。
因此,我建议使用代表您的 JSON 数据的数据 class。
例如,
定义一个映射器,
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@d486a4d
scala> mapper.registerModule(DefaultScalaModule)
res0: com.fasterxml.jackson.databind.ObjectMapper = $anon@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)
最佳解决方案是定义一个数据 class,我在下面的示例中调用 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)
直接读取JSON作为JsonNode,直接访问属性:
val jsonNode = objectMapper.readTree(json.reader())
val parsedJson = jsonNode.get("category").asText
通过使用 scala 泛型函数将 JSON 字符串转换为大小写 Class/Object,您可以反序列化为您想要的任何内容。喜欢
JSON to Collection
、
JSON to Case Class
和
JSON to Case Class with Object as field
。
请找到我使用泛型提供的有效且详细的答案 here。
我的 JSON 文件包含以下详细信息 { "category":"age, gender,post_code" }
我的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) = example List(age, gender,post_code) 但我需要 Seq(String) 输出如果有人对此有任何想法请帮助我。
scala 中的想法是尽可能实现类型安全,而您使用 Map[String, Any]
放弃了这一点。
因此,我建议使用代表您的 JSON 数据的数据 class。
例如,
定义一个映射器,
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@d486a4d
scala> mapper.registerModule(DefaultScalaModule)
res0: com.fasterxml.jackson.databind.ObjectMapper = $anon@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)
最佳解决方案是定义一个数据 class,我在下面的示例中调用 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)
直接读取JSON作为JsonNode,直接访问属性:
val jsonNode = objectMapper.readTree(json.reader())
val parsedJson = jsonNode.get("category").asText
通过使用 scala 泛型函数将 JSON 字符串转换为大小写 Class/Object,您可以反序列化为您想要的任何内容。喜欢
JSON to Collection
、JSON to Case Class
和JSON to Case Class with Object as field
。
请找到我使用泛型提供的有效且详细的答案 here。