2

私はplayframework 2で組み込みのjersonを使用しています。私が望むのは、異なるタイプの値を含むマップをシリアライズすることだけです:

object AppWriter extends Writes[Application] {
    def writes(app: Application): JsValue = {
        Json.toJson(Map(
            "id" -> app.getId.toString,
            "name" -> app.getName,
            "users" -> Seq(1, 2, 3)
        ))
    }
}

この場合、私は持っています:

No Json deserializer found for type scala.collection.immutable.Map[java.lang.String,java.lang.Object]. 
Try to implement an implicit Writes or Format for this type

フレームワーク コードをナビゲートすると、 Map[String,V] 型の暗黙的な def mapWrites[V] .. のシリアライザーがあることが示されますが、なぜそれが適用されないのか理解できません。

誰でも私を助けることができますか?

UPD :簡単な回避策を見つけました:

object AppWriter extends Writes[Application] {
def writes(app: Application): JsValue = {
    Json.toJson(Map[String, JsValue](
        "id" -> JsNumber(BigDecimal(app.getId)),
        "name" -> JsString(app.getName),
        "users" -> JsArray(Seq(1, 2, 3).map(x => JsNumber(x)))
    ))
}

}

しかし、これはそれほどエレガントではありません...

4

1 に答える 1

1

これを行う標準的な方法はJsObject、ペアをマップに入れるのではなく、フィールドの個々のキーと値のペアから を作成することです。たとえば、Application次のように見えるとします。

case class Application(getId: Int, getName: String)

あなたは書くことができます:

import play.api.libs.json._, Json.toJson

implicit object AppWriter extends Writes[Application] {
  def writes(app: Application): JsValue = JsObject(
    Seq(
      "id"    -> JsNumber(app.getId),
      "name"  -> JsString(app.getName),
      "users" -> toJson(Seq(1, 2, 3))
    )
  )
}

その後:

scala> toJson(Application(1, "test"))
res1: play.api.libs.json.JsValue = {"id":1,"name":"test","users":[1,2,3]}

シリアル化の方法を詳しく説明する必要はないことに注意してくださいSeq[Int]— デフォルトのFormatインスタンスが作業を行います。

于 2012-12-16T16:21:09.223 に答える