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

时间:2011-06-07 20:43:07

标签: json scala serialization map lift

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

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

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

你们中的任何人都知道怎么做吗?

7 个答案:

答案 0 :(得分:33)

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

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

答案 1 :(得分:26)

这个怎么样?

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))))

输出:

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

编辑:

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

答案 2 :(得分:5)

你可以很容易地自己滚动(yay,没有依赖)。这个对类型进行基本处理,并且会像提到的public class MainActivity extends Activity { WebView view; SwipeRefreshLayout mySwipeRefreshLayout; private ProgressBar progressBar; private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AdView adView = (AdView) findViewById(R.id.admob_id); progressBar= (ProgressBar)findViewById(R.id.progressBar2); progressBar.setVisibility(View.VISIBLE); AdRequest adRequest = new AdRequest.Builder() .setRequestAgent("android_studio:ad_template").build(); adView.loadAd(adRequest); mWebView = (WebView) findViewById(R.id.activity_main_webview); final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipelayout); final WebView mWebView = (WebView) findViewById(R.id.activity_main_webview); swipeRefreshLayout.setColorSchemeResources(R.color.refresh,R.color.refresh1,R.color.refresh2); swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { mWebView.reload(); swipeRefreshLayout.setRefreshing(true); (new Handler()).postDelayed(new Runnable() { @Override public void run() { mWebView.stopLoading(); swipeRefreshLayout.setRefreshing(false); } },10000); } }); // Force links and redirects to open in the WebView instead of in a browser //mWebView.setWebViewClient(new WebViewClient()); // Enable Javascript WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); mWebView.getSettings().setUseWideViewPort(true); mWebView.getSettings().setLoadWithOverviewMode(true); // Use remote resource mWebView.loadUrl("http:google.com"); // Stop local links and redirects from opening in browser instead of WebView mWebView.setWebViewClient(new MyAppWebViewClient()); // Use local resource //mWebView.loadUrl("file:android_asset/web/google.html"); progressBar.setVisibility(View.GONE); } 那样进行递归:

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("\"" , "\\\\\"");
  }
}

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

答案 3 :(得分:3)

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

import play.api.libs.json._

Json.toJson(<your_map>)

答案 4 :(得分:1)

此代码将转换许多不同的对象,并且不需要内置scala.util.parsing.json._之外的任何库。它不能正确处理像整数映射的边缘情况作为键。

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)
  })
}

答案 5 :(得分:0)

与Einar的解决方案类似,您可以使用Parser Combinators中的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

答案 6 :(得分:0)

补充@Raja的答案。

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

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

然后在Map对象中,我使用此MList而不是标准List。这样,我的map对象通过调用JSONObject(map).toString()打印出来。