我们使用Scala 2.11.8
和Play framework 2.5.8
使用的数据可以很简单:
object EnumA extends Enumeration {
type EnumA = Value
val ONE, TWO, THREE = Value
}
case class NoWork(data: Map[EnumA.Value, String] = Map.empty)
我要存档的是能够将NoWork
类解析为Json
。我知道,它需要为提供隐式格式化程序Enumeration
。
我找到了这个解决方案:https : //stackoverflow.com/a/15489179/1549135并应用了它。
提供这些隐式内容的伴随对象如下所示:
object NoWork {
implicit val enumAFormat = EnumUtils.enumFormat(EnumA)
implicit val jsonModelFormat = Json.format[NoWork]
}
它总是失败并显示错误:
error: No implicit format for Map[EnumA.Value,String] available.
implicit val jsonModelFormat = Json.format[NoWork]
^
有什么问题?
我已经测试并更改了data
类型以Map[String, String]
允许序列化。在Enum
对自己的序列化了,所以现在-如何修复Map
与Enum
类型?
谢谢!
编辑
作为帕姆的答案
implicit val writes = new Writes[Map[EnumA.Value, String]] {
override def writes(o: Map[EnumA.Value, String]): JsValue = Json.toJson(o.map { case (a, b) => Json.parse(s"""{${Json.toJson(a)}:${Json.toJson(b)}}""")}.toList)
}
显然可以在这种情况下工作,我实际上需要一个通用的解决方案,供Map[Enum, T]
我在整个应用程序中使用。
与同事一起,我们准备了一个通用类,该类为Map[E <: Enum[E], T]
类型提供JSON序列化。
该Enum
类型始终会转换String
为所需的类型JsObject
key
。另一个参数是通用参数,可使用implicit format: Format[T]
import play.api.data.validation.ValidationError
import play.api.libs.json._
import scala.util.{Failure, Success, Try}
class MapEnumFormat[E <: Enum[E], T](valueOf: (String => E))(implicit format: Format[T]) extends Format[Map[E, T]] {
override def writes(o: Map[E, T]): JsValue = {
JsObject(o.map { case (a, b) => (a.name, Json.toJson(b)) })
}
override def reads(json: JsValue): JsResult[Map[E, T]] = {
val result = Try(json.as[Map[String, T]].map {
case (key, value) =>
valueOf(key) -> value
})
result match {
case Success(status) =>
JsSuccess(status)
case Failure(th) =>
JsError(ValidationError(s"Error while serializing $json: $th"))
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句