Scala到JSON在Play Framework 2.1中
我正在尝试将Scala转换为2.1RC Play Framework中的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","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","33"]) scala> Json.toJson(c) res36: play.api.libs.json.JsValue = {"aa":"xxxx","bb":["11","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,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) 解决方法
播放2.1 JSON API不提供类型映射[String,Ojbect]的序列化程序。
为特定类型定义案例类和格式,而不是Map [String,Object]: // { "val1" : "xxx","val2" : ["a","c"] } case class Hoge(val1: String,val2: List[String]) implicit val hogeFormat = Json.format[Hoge] 如果你不想创建case类。 implicit val objectMapFormat = new Format[Map[String,Object]] { def writes(map: Map[String,Object]): JsValue = Json.obj( "val1" -> map("val1").asInstanceOf[String],"val2" -> map("val2").asInstanceOf[List[String]] ) def reads(jv: JsValue): JsResult[Map[String,Object]] = JsSuccess(Map("val1" -> (jv "val1").as[String],"val2" -> (jv "val2").as[List[String]])) } 更动态 import play.api.libs.json._ import play.api.libs.json.Reads._ import play.api.libs.json.Json.JsValueWrapper implicit val objectMapFormat = new Format[Map[String,Object]): JsValue = Json.obj(map.map{case (s,o) => val ret:(String,JsValueWrapper) = o match { case _:String => s -> JsString(o.asInstanceOf[String]) case _ => s -> JsArray(o.asInstanceOf[List[String]].map(JsString(_))) } ret }.toSeq:_*) def reads(jv: JsValue): JsResult[Map[String,Object]] = JsSuccess(jv.as[Map[String,JsValue]].map{case (k,v) => k -> (v match { case s:JsString => s.as[String] case l => l.as[List[String]] }) }) } 示例代码: val jv = Json.toJson(Map("val1" -> "xxx","val2" -> List("a","c"),"val3" -> "sss","val4" -> List("d","e","f"))) println(jv) val jr = Json.fromJson[Map[String,Object]](jv) println(jr.get) 输出: > {"val1":"xxx","val2":["a","c"],"val3":"sss","val4":["d","f"]} > Map(val1 -> xxx,c),val3 -> sss,val4 -> List(d,e,f)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |