我有一个 Play-scala v2.3 应用程序。从this guide about Json Combinators看,我正在尝试这样做:
object Application extends Controller {
case class Foo(id: String, docs: List[Map[String, _]])
implicit val fooReads = (
(JsPath \ "id").read[String] and
(JsPath \ "docs").read[List[Map[String, _]]]
)(Foo.apply _)
...
}
但是后来我遇到了编译错误:
No Json deserializer found for type List[Map[String, _]]. Try to implement an implicit Reads or Format for this type.
(JsPath \ "docs").read[List[Map[String, _]]]
^
这是需要读取的示例 json:
{
"id": "001",
"docs": [
{
"name": "Billy",
"level": 2,
"marked": false
},
{
"name": "Fred",
"level": 5,
"marked": true
}
]
}
我也尝试过这个:
case class Foo(id: String, docs: Map[String, _])
implicit val fooReads = (
(JsPath \ "id").read[String] and
(JsPath \ "docs").read[Map[String, _]]
)(Foo.apply _)
同样的错误。
Play 的 JSON 组合器似乎不适用于 Map
类型。有谁知道如何解决这个问题吗?
最佳答案
避免使用 Map[String, Any]
会更好,Scala 和 Play 使这一切变得简单。更好的解决方案是为您尝试表示为 map 的事物定义自定义案例类:
import play.api.libs.json._
case class Doc(name: String, level: Int, marked: Boolean)
case class Foo(id: String, docs: List[Doc])
implicit val docFormat = Json.format[Doc]
implicit val fooFormat = Json.format[Foo]
val json = Json.parse(...)
然后:
scala> json.as[Foo]
res0: Foo = Foo(001,List(Doc(Billy,2,false), Doc(Fred,5,true)))
或者如果您想要更多控制:
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val fooReads: Reads[Foo] = (
(__ \ 'id).read[String] and
(__ \ 'docs).read(
Reads.list((
(__ \ 'name).read[String] and
(__ \ 'level).read[Int] and
(__ \ 'marked).read[Boolean]
)(Doc.apply _))
)
)(Foo.apply _)
如果您确实需要Map[String, Any]
,您可以随时在Doc
上编写转换方法。
关于Play scala 2.x 中的 JSON 读取组合器不适用于 Map[String, _],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28950577/