Scala获取地图对象上特定数据类型的JSON值

时间:2018-11-17 10:55:35

标签: json scala jackson

使用 jackson 库,我从文件(文件的每一行都是一个JSON对象)读取json数据,并将其解析为 String 的映射对象任何。我的目标是将指定的键(ID和文本)保存到集合中。

val input = scala.io.Source.fromFile("data.json").getLines()
val mapper = new ObjectMapper() with DefaultScalaModule
val data_collection = mutable.HashMap.empty[Int, String]

for (i <- input){
      val parsedJson = mapper.readValue[Map[String, Any]](i)
      data_collection.put(
        parsedJson.get("id"),
        parsedJson.get("text")
      )

但是由于 parsedJson 映射中的值具有 Any 类型,因此获得了诸如 id text ,它将返回 Some(value),而不仅仅是具有适当类型的值。我希望 id 键的值是Integer,而 text 的值是String。 运行代码时出现错误:

Error:(31, 23) type mismatch;
 found   : Option[Any]
 required: Int
        parsedJson.get("id"),

以下是文件中JSON数据的示例:

{"text": "Hello How are you", "id": 1}

在Scala中是否可以将id值解析为Int并将文本值解析为String,或者至少将Some(value)转换为Int或String类型的值?

2 个答案:

答案 0 :(得分:2)

尝试以下代码:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import 
 com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

val input = scala.io.Source.fromFile("data.json").getLines() 
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val obj = mapper.readValue[Map[String, Any]](input)
val data_collection = mutable.HashMap.empty[Int, String]
for (i <- c) {
data_collection.put(
  obj.get("id").fold(0)(_.toString.toInt),
  obj.get("text").fold("")(_.toString)
 )
 }
println(data_collection) // Map(1 -> Hello How are you)

答案 1 :(得分:1)

如果您想从Map而不是 Option 中获取纯值,则可以使用()apply)方法-但是它将如果找不到密钥,则引发异常。

第二,Scala类型的系统是静态的而不是动态的,如果您拥有Any,它将在运行时不会更改为IntString,并且编译器将失败-不过,您可以使用asInstanceOf[T]方法强制转换它们,但是如果不能将类型强制转换为目标类型,则会再次抛出异常。

请注意,即使您可以使用上述技巧使代码工作,该代码也不是您在Scala中所期望的。有一些方法可以使代码更具有类型安全性(例如模式匹配),但是将Json解析为类型安全对象是一个老问题,我敢肯定jackson提供了一种将json解析为案例类。如果不去看看circe,那就可以了。