使用Play 2.5我似乎无法序列化Map[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]。尝试实施 这种类型的隐式Writes或Format。
除非我遗漏了一些明显的内容,否则在上面紧紧地存在该类型的隐式格式。
如果我尝试更简单的方法:
Json.toJson(Something(""))
Json.toJson(Map[String, String]("" -> ""))
工作正常。在使用Map
和更复杂的类型(例如SomeCaseClass
?
答案 0 :(得分:4)
我认为这里的问题来自json。映射将转换为由键/值对组成的JSON对象。这些对象must
中的键是字符串。
因此,Map[String, T]
可以转换为json对象,但不能转换为任意Map[U, T]
。
答案 1 :(得分:1)
@Jack Bourne是正确的。映射在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)
}
}