如何在 Scala 中将 Map 序列化为 JSON?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6271386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:52:27  来源:igfitidea点击:

How do you serialize a Map to JSON in Scala?

jsonscalaserializationmaplift

提问by Jay Taylor

So I have a Map in Scala like this:

所以我在 Scala 中有一个像这样的地图:

val m = Map[String, String](
    "a" -> "theA",
    "b" -> "theB",
    "c" -> "theC",
    "d" -> "theD",
    "e" -> "theE"
)

and I want to serialize this structure into a JSON string using lift-json.

我想使用lift-json将此结构序列化为JSON字符串。

Do any of you know how to do this?

你们中有人知道如何做到这一点吗?

回答by Raja

If you are using the latest Scala 2.10.x and above :

如果您使用的是最新的 Scala 2.10.x 及更高版本:

println(scala.util.parsing.json.JSONObject(m))

回答by Raja

How about this?

这个怎么样?

implicit val formats = net.liftweb.json.DefaultFormats
import net.liftweb.json.JsonAST._
import net.liftweb.json.Extraction._
import net.liftweb.json.Printer._
val m = Map[String, String](
    "a" -> "theA",
    "b" -> "theB",
    "c" -> "theC",
    "d" -> "theD",
    "e" -> "theE"
)
println(compact(render(decompose(m))))

output:

输出:

{"e":"theE","a":"theA","b":"theB","c":"theC","d":"theD"}

EDIT:

编辑:

For a scala.collections.mutable.Map, you should convert it first to an immutable map: .toMap

对于 a scala.collections.mutable.Map,您应该先将其转换为不可变映射:.toMap

回答by jar

You can roll your own pretty easily (yay, no dependencies). This one does basic handling of types and will do recursion unlike JSONObjectthat was mentioned:

你可以很容易地推出你自己的(是的,没有依赖关系)。这个做类型的基本处理,并且会做递归,不像JSONObject提到的那样:

import scala.collection.mutable.ListBuffer

object JsonConverter {
  def toJson(o: Any) : String = {
    var json = new ListBuffer[String]()
    o match {
      case m: Map[_,_] => {
        for ( (k,v) <- m ) {
          var key = escape(k.asInstanceOf[String])
          v match {
            case a: Map[_,_] => json += "\"" + key + "\":" + toJson(a)
            case a: List[_] => json += "\"" + key + "\":" + toJson(a)
            case a: Int => json += "\"" + key + "\":" + a
            case a: Boolean => json += "\"" + key + "\":" + a
            case a: String => json += "\"" + key + "\":\"" + escape(a) + "\""
            case _ => ;
          }
        }
      }
      case m: List[_] => {
        var list = new ListBuffer[String]()
        for ( el <- m ) {
          el match {
            case a: Map[_,_] => list += toJson(a)
            case a: List[_] => list += toJson(a)
            case a: Int => list += a.toString()
            case a: Boolean => list += a.toString()
            case a: String => list += "\"" + escape(a) + "\""
            case _ => ;
          }
        }
        return "[" + list.mkString(",") + "]"
      }
      case _ => ;
    }
    return "{" + json.mkString(",") + "}"
  }

  private def escape(s: String) : String = {
    return s.replaceAll("\"" , "\\\"");
  }
}

You can see it in action like

你可以看到它在行动

println(JsonConverter.toJson(
    Map("a"-> 1,
        "b" -> Map(
            "nes\"ted" -> "yeah{\"some\":true"),
            "c" -> List(
                1,
                2,
                "3",
                List(
                    true,
                    false,
                    true,
                    Map(
                        "1"->"two",
                        "3"->"four"
                    )
                )
            )
        )
    )
)

{"a":1,"b":{"nes\"ted":"yeah{\"some\":true"},"c":[1,2,"3",[true,false,true,{"1":"two","3":"four"}]]}

(It's part of a Coinbase GDAX library I've written, see util.scala)

(它是我编写的 Coinbase GDAX 库的一部分,请参阅util.scala

回答by Haimei

You can use this simple way if you are using play framework:

如果您使用的是播放框架,则可以使用这种简单的方法:

import play.api.libs.json._

Json.toJson(<your_map>)

回答by robert

This code will convert many different objects, and doesn't require any libraries beyond the built-in the scala.util.parsing.json._. It won't properly handle edge cases like Maps with integers as keys.

此代码将转换许多不同的对象,并且除了内置的scala.util.parsing.json._. 它不会正确处理边缘情况,例如以整数为键的 Maps。

import scala.util.parsing.json.{JSONArray, JSONObject}
def toJson(arr: List[Any]): JSONArray = {
  JSONArray(arr.map {
    case (innerMap: Map[String, Any]) => toJson(innerMap)
    case (innerArray: List[Any])      => toJson(innerArray)
    case (other)                      => other
  })
}
def toJson(map: Map[String, Any]): JSONObject = {
  JSONObject(map.map {
    case (key, innerMap: Map[String, Any]) =>
      (key, toJson(innerMap))
    case (key, innerArray: List[Any]) =>
      (key, toJson(innerArray))
    case (key, other) =>
      (key, other)
  })
}

回答by Junji Shimagaki

Supplementing the answer by @Raja.

补充@Raja的答案。

For those nested object, I locally modify the class to have my wanted toString()like this way:

对于那些嵌套对象,我在本地修改类,以toString()这样方式获得我想要的:

case class MList[T]() extends MutableList[T] { override def toString() = "[" + this.toList.mkString(",") + "]" }

case class MList[T]() extends MutableList[T] { override def toString() = "[" + this.toList.mkString(",") + "]" }

Then inside the Map object, I use this MListinstead of the standard List. That way, my mapobject prints out fine by calling JSONObject(map).toString().

然后在 Map 对象中,我使用 thisMList而不是标准的List. 这样,我的map对象通过调用JSONObject(map).toString().

回答by jwhitlark

Similar to Einar's solution, you can use JSONObject from Parser Combinatorsto do this. Note that it does not recurse, you'll need to do this yourself. The library also includes JSONArray, for list like data structures. Something like the following will address Noel's concerns about nested structures. This example does not recurse to an arbitrary level, but will handle a value of List[Map[String, Any]].

与 Einar 的解决方案类似,您可以使用Parser Combinator 中的JSONObject来执行此操作。请注意,它不会递归,您需要自己执行此操作。该库还包括 JSONArray,用于类似数据结构的列表。类似下面的内容将解决 Noel 对嵌套结构的担忧。此示例不会递归到任意级别,但会处理List[Map[String, Any]] 的值

import scala.util.parsing.json.{JSONArray, JSONObject}

def toJson(m : Map[String, Any]): String = JSONObject(
  m.mapValues {
    case mp: Map[String, Any] => JSONObject(mp)
    case lm: List[Map[String, Any]] => JSONArray(lm.map(JSONObject(_)))
    case x => x
    }
  ).toString