播放 Map[Int,_] 的 JSON 格式化程序 [英] Play JSON formatter for Map[Int,_]

查看:25
本文介绍了播放 Map[Int,_] 的 JSON 格式化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to migrate a Rails/Mongodb application to Play 2.3 using play-reactivemongo and reactivemongo-extensions. In modeling my data I am running across a problem serializing and deserializing a Map[Int,Boolean].

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

When I try to define my formats via macro like so

implicit val myCaseClass = Json.format[MyCaseClass]

其中 MyCaseClass 有几个字符串字段、一个 BSONObjectID 字段和一个 Map[Int,Boolean] 字段,编译器会抱怨:

where MyCaseClass has a few string fields, a BSONObjectID field, and a Map[Int,Boolean] field the compiler complains with:

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.

查看 Reads.scala 中 Play 的源代码,我看到为 Map[String,_] 定义的读取但没有为 Map[Int,_] 定义的读取.

Looking at the source code for Play in Reads.scala I see a Reads defined for Map[String,_] but none for Map[Int,_].

为什么 Play 有默认的读取/写入字符串映射而不是其他简单类型的原因?

Is there a reason why Play has default Read/Writes for string maps but not for other simple types?

我不完全理解 play 定义的 Map[String,_] ,因为我对 Scala 相当陌生.我将如何将其翻译成 Map[Int,_]?如果由于某些技术原因无法实现,我将如何为 Map[Int,Boolean] 定义读/写?

I don't fully understand the Map[String,_] defined by play because I am fairly new to scala. How would I go about translating that into a Map[Int,_]? If that is not possible for some technical reason how would I define a Reads/Writes for Map[Int,Boolean]?

推荐答案

您可以在 play 中编写自己的读写操作.

you can write your own reads and writes in play.

在你的情况下,这看起来像这样:

in your case, this would look like this:

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)

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

I have tested it with play 2.3. I'm not sure if it's the best approach to have a Map[Int, Boolean] on server side and a json object with string -> boolean mapping on the client side, though.

这篇关于播放 Map[Int,_] 的 JSON 格式化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆