1

REPL で実行すると、動作します (mapWritesスコープ内で暗黙的であるため)。

scala> Map("a"->1l, "b"->2l)
res0: scala.collection.immutable.Map[String,Long] = Map(a -> 1, b -> 2)

scala> Map("c" -> res0, "d" -> res0)
res1:     scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Long]] = Map(c -> Map(a -> 1, b -> 2), d -> Map(a -> 1, b -> 2))

scala> import play.api.libs.json._
import play.api.libs.json._

scala> Json.toJson(res1)
res2: play.api.libs.json.JsValue = {"c":{"a":1,"b":2},"d":{"a":1,"b":2}}

私のコードがまだコンパイルされないのはなぜですか (REPL と同じタイプです)。

No Json deserializer found for type Map[String,Map[String,Long]]. Try to implement an implicit Writes or Format for this type.

[編集] 回避策を見つけましたが、なぜそれが必要なのかわかりません:

implicit def mapWrites = Writes[Map[String,Map[String,Long]]] ( m => Writes.mapWrites(Writes.mapWrites[Long]).writes(m))
4

1 に答える 1

0

Play 2.1 JSON API は Type のシリアライザーを提供しませんMap[String, Object]

の代わりに特定のタイプに対してcase classとを定義します。FormatMap[String, Object]

// { "val1" : "xxx", "val2" : ["a", "b", "c"] }
case class Hoge(val1: String, val2: List[String])

implicit val hogeFormat = Json.format[Hoge]

ケースクラスを作成したくない場合。次のコードは、Map[String, Object] の JSON シリアライザー/デシリアライザーを提供します。

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

Jackson は、Scala コレクション クラスをデシリアライズする方法を知りませんscala.collection.immutable.Map。これは、Java コレクション インターフェイスを実装していないためです。

Java コレクションに逆シリアル化することができます。

val mapData = mapper.readValue(jsonContent, classOf[java.util.Map[String,String]])

または、Scala モジュールをマッパーに追加します。

mapper.registerModule(DefaultScalaModule)
val mapData = mapper.readValue(jsonContent, classOf[Map[String,String]])

または、このように試すこともできます

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)

そして、それはうまくいきます。

于 2013-11-14T10:48:23.057 に答える