Parsing JSON in Play2 and Scala without Data Type
Asked Answered
H

2

15
{
  "people": [
    {
      "name": "Jack",
      "age": 15
    },
    {
      "name": "Tony",
      "age": 23
    },
    {
      "name": "Mike",
      "age": 19
    }
  ]
}

Thats a sample of the json I'm trying to parse through. I want to be able to do a foreach operation on each person and println their name and age.

I know how to handle json arrays when it's a single item or a specific numbered item. I don't know how to iterate through all items.

Can anyone help me out?

Homes answered 26/3, 2013 at 17:38 Comment(1)
Note: I am also open to using a completely different library for JSON than what is integrated with Play. But, I'd prefer not to.Homes
L
25

There are many ways to do this with the Play JSON Library. The main difference is the usage of Scala case class or not.

Given a simple json

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

You can use case class and Json Macro to automatically parse the data

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)

Or without case class, manually

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)

In other words, check the very complete documentation on this subject :) http://www.playframework.com/documentation/2.1.0/ScalaJson

Lobotomy answered 26/3, 2013 at 18:46 Comment(5)
My real usecase is a bit more complex than the json sample I gave. Is it possible to only read the names and completely ignore the age? Or must you always convert the entire json into a scala case class?Homes
(json \ "people" \\ "name") ?Lobotomy
This did not work for me. It keeps saying that there is no deserializer for List[People]]. Json.reads also did not work for me. I am on Play 2.0.4Homes
Have you check playframework.com/documentation/2.0.4/ScalaJsonGenerics ? There are many samples. And I think the code in my last comment works with 2.0.4.Lobotomy
.as[T] is unsafe. Use .asOpt[T] or .validate[T]Siskin
R
4

If you don't have the object type or don't want to write a Reads, you can use .as[Array[JsValue]]

val jsValue = Json.parse(text)
val list = (jsValue \ "people").as[Array[JsValue]]

Then

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

In the older version (2.6.x) it is possible to use .as[List[JsValue]] but newer versions only support Array.

Rembrandt answered 18/3, 2018 at 10:15 Comment(1)
this...if you just want a couple of fields from a huge industrial rest API listLotte

© 2022 - 2024 — McMap. All rights reserved.