从 json 列表中读取的播放框架

Play framework read from json list

所以我在 json 中有一个结构如下所示:

{
    "lst": [
        {"name": "foo"},
        {"name": "bar"}
    ]
}

我很难将其转换为案例列表 classes。我确定我遗漏了一些非常明显的东西...

我试过这个:

case class Person(name: String)
implicit val personReads: Reads[Email] = (__ \  "name").read[String](Person)

// endpoint
def person = Action { request =>
    val person = request.body.asJson.get.as[Seq[Person]]
}

无法编译,因为 read 没有 return 和 FunctionBuilder,这意味着我无法将路径应用到 Person

添加新参数确实编译(相应地更改 json 和大小写 class):

case class Person(name: String, age: String)
implicit val personReads: Reads[Email] = (
    (__ \  "name").read[String]) and 
    (__ \  "age").read[Int](Person)

但会抛出异常 Execution exception[[JsResultException: JsResultException(errors:List((,List(ValidationError(List(error.expected.jsarray),WrappedArray())))))]] 据说是因为它需要一个列表。

所以我尝试添加这个:

implicit val personsReads: Reads[Seq[Person]] = (__ \ "lst").read[Seq[Person]]

然后抛出 NullPointer.

最后我只想要一个Seq[Person]。 谁能给我指出正确的方向,我完全不知道我应该在这里做什么...

您可以执行以下操作,而不是显式地提供读取和写入。

import play.api.json.Json

case class Person(name: String)
object Person {
  implicit val personFormat = Json.format[Person]
}

case class Persons(lst: List[Person])

object Persons {
 implicit val personsFormat = Json.format[Persons]
}

现在取 json 字符串让我们说 jsonStr

Json.parse(jsonStr).validate[Persons] match {
 case JsSuccess(persons, _) => println(persons)
 case JsError(_) => println("parsing failed")
}

Scala REPL

scala> import play.api.libs.json._
import play.api.libs.json._

scala> val str = """{
     |     "lst": [
     |         {"name": "foo"},
     |         {"name": "bar"}
     |     ]
     | }""".stripMargin
str: String =
{
    "lst": [
        {"name": "foo"},
        {"name": "bar"}
    ]
}

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Person(name: String)
object Person {
  implicit val personFormat = Json.format[Person]
}

case class Persons(lst: List[Person])

object Persons {
 implicit val personsFormat = Json.format[Persons]
}

// Exiting paste mode, now interpreting.

defined class Person
defined object Person
defined class Persons
defined object Persons

scala> val jsonStr = str
jsonStr: String =
{
    "lst": [
        {"name": "foo"},
        {"name": "bar"}
    ]
}

scala> :paste
// Entering paste mode (ctrl-D to finish)

Json.parse(jsonStr).validate[Persons] match {
 case JsSuccess(persons, _) => println(persons)
 case JsError(_) => println("parsing failed")
}

// Exiting paste mode, now interpreting.

Persons(List(Person(foo), Person(bar)))

现在,当您更改 Person 案例 class 并添加 age 字段时。

case class Person(name: String, age: Int)

object Person {
 implicit val personFormat = Json.format[Person]
}

确保您尝试解析的 json 包含姓名和年龄。如果你只有名字那么你会得到解析错误。