播放Map [Int,_]的JSON格式化程序

ima*_*gio 9 json scala playframework playframework-2.3

我正在尝试使用play-reactivemongo和reactivemongo-extensions将Rails/Mongodb应用程序迁移到Play 2.3.在建模我的数据时,我遇到了一个问题,即序列化和反序列化Map [Int,Boolean].

当我尝试通过宏来定义我的格式时

implicit val myCaseClass = Json.format[MyCaseClass]
Run Code Online (Sandbox Code Playgroud)

其中MyCaseClass有一些字符串字段,一个BSONObjectID字段,以及编译器抱怨的Map [Int,Boolean]字段:

No Json serializer found for type Map[Int,Boolean]. Try to implement an implicit Writes or Format for this type.
No Json deserializer found for type Map[Int,Boolean]. Try to implement an implicit Reads or Format for this type.
Run Code Online (Sandbox Code Playgroud)

查看Play in Reads.scala中的源代码,我看到为Map [String,_]定义了一个Read,但没有为Map [Int,_]定义.

Play是否有字符串映射的默认读/写,而其他简单类型没有?

我不完全理解play定义的Map [String,_],因为我对scala相当新.我如何将其转换为Map [Int,_]?如果由于某些技术原因这是不可能的,我如何定义Map [Int,Boolean]的读/写?

pic*_*ter 16

你可以在游戏中编写自己的读写.

在你的情况下,这将是这样的:

implicit val mapReads: Reads[Map[Int, Boolean]] = new Reads[Map[Int, Boolean]] {
    def reads(jv: JsValue): JsResult[Map[Int, Boolean]] =
        JsSuccess(jv.as[Map[String, Boolean]].map{case (k, v) =>
            Integer.parseInt(k) -> v .asInstanceOf[Boolean]
        })
}

implicit val mapWrites: Writes[Map[Int, Boolean]] = new Writes[Map[Int, Boolean]] {
    def writes(map: Map[Int, Boolean]): JsValue =
        Json.obj(map.map{case (s, o) =>
            val ret: (String, JsValueWrapper) = s.toString -> JsBoolean(o)
            ret
        }.toSeq:_*)
}

implicit val mapFormat: Format[Map[Int, Boolean]] = Format(mapReads, mapWrites)
Run Code Online (Sandbox Code Playgroud)

我用play 2.3进行了测试.我不确定这是否是在服务器端使用Map [Int,Boolean]和在客户端使用字符串 - >布尔映射的json对象的最佳方法.


Set*_*sue 7

JSON只允许字符串键(它从JavaScript继承的限制).