在Play2和Scala中解析JSON,不需要数据类型

15
{
  "people": [
    {
      "name": "Jack",
      "age": 15
    },
    {
      "name": "Tony",
      "age": 23
    },
    {
      "name": "Mike",
      "age": 19
    }
  ]
}
这是我试图解析的 JSON 示例。我想能够对每个人执行 foreach 操作,然后打印出他们的姓名和年龄。
当JSON数组只有单个项或特定编号的项时,我知道如何处理它。但我不知道如何迭代所有项。有人能帮帮我吗?

注意:我也可以使用与Play集成不同的JSON库。但我宁愿不这样做。 - Commander
2个回答

25

使用Play JSON库有许多方法。主要区别在于是否使用Scala case class。

给定一个简单的JSON:

val json = Json.parse("""{"people": [ {"name":"Jack", "age": 19}, {"name": "Tony", "age": 26} ] }""")

您可以使用case class和Json Macro来自动解析数据

import play.api.libs.json._

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

implicit val peopleReader = Json.reads[People]
val peoples = (json \ "people").as[List[People]]
peoples.foreach(println)

或者手动地,不使用 case class

import play.api.libs.json._
import play.api.libs.functional.syntax._

implicit val personReader: Reads[(String, Int)] = (
  (__ \ "name").read[String] and 
  (__ \ "age").read[Int]
).tupled
val peoples = (json \ "people").as[List[(String, Int)]]
peoples.foreach(println)

换句话说,查看有关此主题的非常完整的文档 :) http://www.playframework.com/documentation/2.1.0/ScalaJson


我的实际用例比我给出的JSON示例要复杂一些。是否可能仅读取名称并完全忽略年龄?或者必须始终将整个JSON转换为Scala case类? - Commander
1
(json \ "people" \\ "name") - Julien Lafont
这对我来说没用。它一直说没有List[People]]的反序列化程序。Json.reads 对我也没用。我使用的是Play 2.0.4版本。 - Commander
你检查过http://www.playframework.com/documentation/2.0.4/ScalaJsonGenerics吗?那里有很多示例。而且我认为我最后一条评论中的代码可与2.0.4一起使用。 - Julien Lafont
4
.as[T] 是不安全的。请使用 .asOpt[T].validate[T] - Ashesh

4
如果您没有对象类型或者不想编写一个 Reads,您可以使用 .as[Array[JsValue]]
val jsValue = Json.parse(text)
val list = (jsValue \ "people").as[Array[JsValue]]

那么

list.foreach(a => println((a \ "name").as[String]))

在旧版本(2.6.x)中,可以使用.as[List[JsValue]],但新版本只支持Array。

如果您只需要从一个庞大的工业REST API列表中获取几个字段,可以使用这个... - Jake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接