我正在尝试在 2.1RC Play Framework 中将 Scala 转换为 JSON。
我可以执行以下操作并获取 JSON:
import play.api.libs.json._
val a1=Map("val1"->"a", "val2"->"b")
Json.toJSon(a1)
因为 a1 只是 Map[String,String] 可以正常工作。
但是如果我有一些更复杂的东西,比如我有 Map[String,Object],那是行不通的:
val a = Map("val1" -> "xxx", "val2"-> List("a", "b", "c"))
Json.toJSon(a1)
>>> error: No Json deserializer found for type scala.collection.immutable.Map[String,Object]
我发现我可以执行以下操作:
val a2 = Map("val1" -> Json.toJson("a"), "val2" -> Json.toJson(List("a", "b", "c")))
Json.toJson(a2)
那行得通。
但是我怎么能以一般的方式做到这一点?我认为我可以执行以下操作:
a.map{ case(k,v)=> (k, Json.toJson(v) )}
>>> error: No Json deserializer found for type Object
但我仍然收到无法反序列化的错误
附加信息:
Json.toJson 可以将 Map[String, String] 转换为 JsValue:
scala> val b = Map( "1" -> "A", "2" -> "B", "3" -> "C", "4" -> "D" )
b: scala.collection.immutable.Map[String,String] = Map(1 -> A, 2 -> B, 3 -> C, 4 -> D)
scala> Json.toJson(b)
res31: play.api.libs.json.JsValue = {"1":"A","2":"B","3":"C","4":"D"}
但是,它无法尝试转换 Map[String, Object]:
scala> a
res34: scala.collection.immutable.Map[String,Object] = Map(val1 -> xxx, val2 -> List(a, b, c))
scala> Json.toJson(a)
<console>:12: error: No Json deserializer found for type scala.collection.immutable.Map[String,Object]. Try to implement an implicit Writes or Format for this type.
Json.toJson(a)
使用此 Play Framework 页面中关于将 Scala 转换为 Json 的“提示”,我发现以下内容(http://www.playframework.org/documentation/2.0.1/ScalaJson):
如果不是 Map[String, Object],而是 Map[String, JsValue],那么 Json.toJson() 将起作用:
scala> val c = Map("aa" -> Json.toJson("xxxx"), "bb" -> Json.toJson( List("11", "22", "33") ) )
c: scala.collection.immutable.Map[String,play.api.libs.json.JsValue] = Map(aa -> "xxxx", bb -> ["11","22","33"])
scala> Json.toJson(c)
res36: play.api.libs.json.JsValue = {"aa":"xxxx","bb":["11","22","33"]}
所以,我想要的是,给定一个 Map[String, Object],我知道 Object 值最初都是 String 或 List[String] 类型,如何将函数 Json.toJson() 应用于所有映射中的值并获取 Map[String, JsValue]。
我还发现我可以过滤掉那些纯粹是字符串的值和那些(曾经)是 List[String] 类型的值:
scala> val a1 = a.filter({case(k,v) => v.isInstanceOf[String]})
a1: scala.collection.immutable.Map[String,Object] = Map(val1 -> xxx)
scala> val a2 = a.filter({case(k,v) => v.isInstanceOf[List[String]]})
<console>:11: warning: non-variable type argument String in type List[String] is unchecked since it is eliminated by erasure
val a2 = a.filter({case(k,v) => v.isInstanceOf[List[String]]})
^
a2: scala.collection.immutable.Map[String,Object] = Map(val2 -> List(a, b, c))
List[String] 过滤会给出警告,但似乎给出了我想要的答案。如果可以应用这两个过滤器,然后将 Json.toJson() 用于结果的值,并将结果组合起来,也许这会起作用?
但是过滤后的结果仍然是 Map[String, Object] 类型,这会导致问题:
scala> Json.toJson(a1)
<console>:13: error: No Json deserializer found for type scala.collection.immutable.Map[String,Object]. Try to implement an implicit Writes or Format for this type.
Json.toJson(a1)