Play scala 2.x 中的 JSON 读取组合器不适用于 Map[String, _]

标签 json scala playframework playframework-2.0

我有一个 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/

相关文章:

java - 比较列表时 Scala FunSuite "should be"和 "==="之间的差异

scala - 类似元组类型的递归类型

twitter-bootstrap - 在 Play 2.x 中覆盖 WebJar Assets

javascript - 将 JSON 文件加载到 Cytoscape.js 中

scala - 如何使用 `ssc.fileStream()` 读取 Parquet 文件?传递给 `ssc.fileStream()` 的类型是什么?

java - Play Framework - 使用 JPA 的分页

email - 在 Heroku 托管的 Play Framework 2 应用程序上通过 Mandrill 对电子邮件进行错误的内容传输编码。在本地工作

json - 如何在单页应用程序中使用 SecureSocial

java - 无法在 AsyncTask 中获取经纬度

ios - 使用 RESTKit 映射带有括号的 JSON 响应