Scala 播放框架:地图没有隐式格式
使用Play 2.5,我似乎无法序列化Scala 播放框架:地图没有隐式格式,scala,playframework,playframework-2.5,play-json,Scala,Playframework,Playframework 2.5,Play Json,使用Play 2.5,我似乎无法序列化映射[SomeCaseClass,String] case class SomeCaseClass(value: String) implicit val formatSomeCaseClass = Json.format[SomeCaseClass] Json.toJson(Map[SomeCaseClass, String](SomeCaseClass("") -> "")) 错误 未找到类型的Json序列化程序 scala.collecti
映射[SomeCaseClass,String]
case class SomeCaseClass(value: String)
implicit val formatSomeCaseClass = Json.format[SomeCaseClass]
Json.toJson(Map[SomeCaseClass, String](SomeCaseClass("") -> ""))
错误
未找到类型的Json序列化程序
scala.collection.immutable.Map[SomeCaseClass,String]。设法实施
此类型的隐式写入或格式
除非我遗漏了一些明显的东西,否则上面的类型有一个隐式格式
如果我尝试更简单的方法,例如:
Json.toJson(Something(""))
Json.toJson(Map[String, String]("" -> ""))
它很好用。当将
映射
与更复杂的类型(例如SomeCaseClass
)一起使用时,我遗漏了什么?我认为这里的问题来自json。映射被转换为由键/值对组成的JSON对象。这些对象中的键必须是字符串
因此,Map[String,T]
可以转换为json对象,但不能转换为任意的Map[U,T]
@jackbourne是正确的。映射在play json中被视为JsObject,因此键必须可序列化为字符串值
下面是一个示例代码,可用于定义地图格式
import play.api.libs.json._
case class SomeCaseClass(value: String)
implicit val formatSomeCaseClass = Json.format[SomeCaseClass]
Json.toJson(Map[SomeCaseClass, String](SomeCaseClass("") -> ""))
implicit val someCaseClassToStringFormat = new Format[Map[SomeCaseClass, String]] {
override def writes(o: Map[SomeCaseClass, String]): JsValue = {
val tuples = o.toSeq.map {
case (key, value) => key.value -> Json.toJsFieldJsValueWrapper(value)
}
Json.obj(tuples: _*)
}
override def reads(json: JsValue): JsResult[Map[SomeCaseClass, String]] = {
val resultMap: Map[SomeCaseClass, String] = json.as[JsObject].value.toSeq.map {
case (key, value) => Json.fromJson[SomeCaseClass](value) match {
case JsSuccess(someCaseClass, _) => someCaseClass -> key
case JsError(errors) => throw new Exception(s"Unable to parse json :: $value as SomeCaseClass because of ${JsError.apply(errors)}")
}
}(collection.breakOut)
JsSuccess(resultMap)
}
}
它对我有用-请看@pme我想知道它是否是scala/play版本的东西,我使用的是Play2.5它看起来像-ScalaFIDLE在我正确回忆时使用的是2.6。无论如何,它生成的格式不是您想要的格式;)。是的,我想你是对的,我交换了键和值,它就工作了,谢谢如果我的case类只是一个字符串的包装器,你能想出任何方法让它工作吗?最简单的方法可能是删除你的case类我问的原因是我希望用枚举替换我的case类,因此,它只会序列化为字符串如果您只想写入它,您可以在写入相应字符串之前映射枚举值:mapToWrite.map{case(key,value)=>(key.toString,value)}