Parsing JSON in Play2 and Scala without Data Type

14,372

Solution 1

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

Solution 2

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.

Share:
14,372
Commander
Author by

Commander

Programmer for 10 years. Currently working at a hot startup in New York City.

Updated on June 30, 2022

Comments

  • Commander
    Commander almost 2 years
    {
      "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?

    • Commander
      Commander about 11 years
      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.
  • Commander
    Commander about 11 years
    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?
  • Julien Lafont
    Julien Lafont about 11 years
    (json \ "people" \\ "name") ?
  • Commander
    Commander about 11 years
    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.4
  • Julien Lafont
    Julien Lafont about 11 years
    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.
  • Ashesh
    Ashesh about 9 years
    .as[T] is unsafe. Use .asOpt[T] or .validate[T]
  • Jake
    Jake about 5 years
    this...if you just want a couple of fields from a huge industrial rest API list