How to parse JSON data into an array of Scala objects

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 15.4, “How to parse JSON data into an array of Scala objects.”

Problem

You have a JSON string that represents an array of objects, and you need to deserialize it into objects you can use in your Scala application.

Solution

Use a combination of methods from the Lift-JSON library. The following example demonstrates how to deserialize the string jsonString into a series of EmailAccount objects, printing each object as it is deserialized:

import net.liftweb.json.DefaultFormats
import net.liftweb.json._

// a case class to match the JSON data
case class EmailAccount(
    accountName: String,
    url: String,
    username: String,
    password: String,
    minutesBetweenChecks: Int,
    usersOfInterest: List[String]
)

object ParseJsonArray extends App {
    implicit val formats = DefaultFormats

    // a JSON string that represents a list of EmailAccount instances
    val jsonString ="""
    {
      "accounts": [
    { "emailAccount": {
      "accountName": "YMail",
      "username": "USERNAME",
      "password": "PASSWORD",
      "url": "imap.yahoo.com",
      "minutesBetweenChecks": 1,
      "usersOfInterest": ["barney", "betty", "wilma"]
    }},
    { "emailAccount": {
      "accountName": "Gmail",
      "username": "USER",
      "password": "PASS",
      "url": "imap.gmail.com",
      "minutesBetweenChecks": 1,
      "usersOfInterest": ["pebbles", "bam-bam"]
    }}]}
    """

    // json is a JValue instance
    val json = parse(jsonString)
    val elements = (json \\ "emailAccount").children
    for (acct <- elements) {
        val m = acct.extract[EmailAccount]
        println(s"Account: ${m.url}, ${m.username}, ${m.password}")
        println(" Users: " + m.usersOfInterest.mkString(","))
    }
}

Running this program results in the following output:

Account: imap.yahoo.com, USERNAME, PASSWORD
  Users: barney,betty,wilma
Account: imap.gmail.com, USER, PASS
  Users: pebbles,bam-bam

Discussion

I use code like this in my SARAH application to notify me when I receive an email message from people in the usersOfInterest list. SARAH scans my email inbox periodically, and when it sees an email message from people in this list, it speaks, “You have new email from Barney and Betty.”

This example begins with some sample JSON stored in a string named jsonString. This string is turned into a JValue object named json with the parse function. The json object is then searched for all elements named emailAccount using the \\ method. This syntax is nice, because it’s consistent with the XPath-like methods used in Scala’s XML library.

The for loop iterates over the elements that are found, and each element is extracted as an EmailAccount object, and the data in that object is then printed.

Notice that the EmailAccount class has the usersOfInterest field, which is defined as List[String]. The Lift-JSON library converts this sequence easily, with no additional coding required.

See Also