播放框架从json列表中读取

时间:2017-02-18 09:09:39

标签: json scala playframework-2.0

所以我在json中有一个看起来像这样的结构:

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

我最难将其转换为案例类列表。我确定我错过了一些完全明显的东西......

我试过这个:

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没有返回FunctionBuilder而无法编译,这意味着我无法将路径应用于Person

添加新参数会编译(相应地更改json和case类):

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]。 任何人都可以指出我正确的方向,我完全迷失了我期望在这里做的事情......

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作,而不是明确地进行读取和写入。

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案例类并添加age字段时。

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

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

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