如何将JSON字符串转换为Scala Map?

18

我有一个嵌套的JSON,其结构未定义。每次运行时都可能不同,因为我正在从远程文件中读取。我需要将此JSON转换为Map [String,Any]类型的映射。我尝试查看了json4s和jackson解析器,但它们似乎无法解决我遇到的问题。有人知道我如何实现这一点吗?

示例字符串:

{"body":{
    "method":"string",
    "events":"string",
    "clients":"string",
    "parameter":"string",
    "channel":"string",
    "metadata":{
        "meta1":"string",
        "meta2":"string",
        "meta3":"string"
    }
},
"timestamp":"string"}

嵌套级别可以是任意的且不预先定义。
为了帮助使用案例:
我有一个类型为 Map[String,Any] 的数据需要备份存储到文件中。因此,我将其转换为 JSON 字符串并存储在文件中。现在,每次我获取新数据时,我需要从文件中获取 JSON,再将其转换回映射并执行一些计算。但我不能将该映射存储在内存中,因为如果作业失败,则会失去该映射。
我需要一个解决方案,将 JSON 字符串转换回我之前转换前的原始映射。


为什么不使用JSON.parseRaw? - turutosiya
你能否发布一个JSON示例以及其他有用的代码或信息? - Garis M Suero
你如何序列化 Any - Chris Martin
2个回答

24

我使用 json4s 3.2.11 尝试了以下方法,它可以正常工作:

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

//...
def jsonStrToMap(jsonStr: String): Map[String, Any] = {
  implicit val formats = org.json4s.DefaultFormats

  parse(jsonStr).extract[Map[String, Any]]
}

也许您没有定义类型为Formatsimplicit val?同时请注意,只要在范围内可找到该值,您无需在每个方法中都定义一个implicit val


嘿@lambdista,代码看起来完美。我想将其作为自定义函数实现在Spark中,但是Spark数据框不支持“任何”引用,我尝试了相同的String,String,但似乎不起作用。你有什么想法可以使其类型特定吗?谢谢。 - knowledge_seeker
@game_changer 有点晚了,但你可以将它转换为 Map[String, String]。我通常会这样解析来自 Spark 配置属性的平面 JSON:if (jsonMap.keySet.forall(_.isInstanceOf[String])) jsonMap.asInstanceOf[Map[String, String]]。我以前使用的是 JSON.parseFull(已弃用),它返回 Some(map: Map[_, _]) - belgacea

6
您可以使用以下代码将JSON字符串解析为Map[String, Any]
import org.json4s._ 
import org.json4s.jackson.JsonMethods._

val jsonMap = parse(jsonString).values.asInstanceOf[Map[String, Any]]

然而,这种方法不具备类型安全性,因此在从Map中提取值时应谨慎使用。

2
parse 的导入是什么? - ottovon
1
@ottovon 导入 org.json4s._ 导入 org.json4s.jackson.JsonMethods._ - user297112

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接