Scala zu JSON in Play Framework 2.1

Ich versuche, Scala in JSON im 2.1RC Play Framework zu konvertieren.

Ich kann Folgendes tun und JSON erhalten:

import play.api.libs.json._

val a1=Map("val1"->"a", "val2"->"b")
Json.toJSon(a1)

Da a1 nur Map [String, String] ist, funktioniert das in Ordnung.

Aber wenn ich etwas Komplexeres habe wie Map [String, Object], funktioniert das nicht:

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]

Ich habe festgestellt, dass ich Folgendes tun kann:

val a2 = Map("val1" -> Json.toJson("a"), "val2" -> Json.toJson(List("a", "b", "c")))
Json.toJson(a2)

Und das funktioniert.

Aber wie kann ich das generell machen? Ich dachte, ich könnte so etwas tun:

a.map{ case(k,v)=> (k, Json.toJson(v) )}
>>> error: No Json deserializer found for type Object

Trotzdem erhalte ich den Fehler, dass es nicht deserialisiert werden kann

Zusätzliche Information:

Json.toJson kann eine Map [String, String] in einen JsValue konvertieren:

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

Der Versuch, eine Map [String, Object] zu konvertieren, schlägt jedoch fehl:

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)

Anhand des Hinweises auf dieser Play Framework-Seite zur Konvertierung von Scala in Json fand ich Folgendes (http://www.playframework.org/documentation/2.0.1/ScalaJson):

Wenn anstelle von Map [String, Object] ein Map [String, JsValue] vorhanden ist, funktioniert 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"]}

Also, was ich möchte, ist, dass bei einer gegebenen Map [String, Object], bei der ich weiß, dass die Object-Werte ursprünglich alle vom Typ String oder List [String] waren, die Funktion Json.toJson () auf all angewendet wird die Werte in der Karte und erhalten eine Karte [String, JsValue].

Ich habe auch herausgefunden, dass ich die Werte herausfiltern kann, die reine Zeichenfolgen sind und die vom Typ List [String] sind (waren):

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

Die List [String] -Filterung gibt eine Warnung aus, scheint aber die gewünschte Antwort zu geben. Wenn die beiden Filter angewendet und dann Json.toJson () für die Werte des Ergebnisses verwendet und die Ergebnisse kombiniert werden könnten, würde das vielleicht funktionieren?

Die gefilterten Ergebnisse sind jedoch weiterhin vom Typ Map [String, Object], was zu einem Problem führt:

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)

Antworten auf die Frage(1)

Ihre Antwort auf die Frage