This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 15.1, “How to create a JSON string from a Scala object.”
Problem
You’re working outside of a specific framework, and want to create a JSON string from a Scala object.
Solution
If you’re using the Play Framework, you can use its library to work with JSON, as shown in Recipes 15.14 and 15.15, but if you’re using JSON outside of Play, you can use the best libraries that are available for Scala and Java:
This recipe demonstrates the Lift-JSON and Gson libraries. (Json4s is a port of Lift-JSON, so it shares the same API.)
Lift-JSON solution
To demonstrate the Lift-JSON library, create an empty SBT test project. With Scala 2.10 and SBT 0.12.x, configure your build.sbt file as follows:
name := "Basic Lift-JSON Demo" version := "1.0" scalaVersion := "2.10.0" libraryDependencies += "net.liftweb" %% "lift-json" % "2.5+"
Next, in the root directory of your project, create a file named LiftJsonTest.scala:
import scala.collection.mutable._ import net.liftweb.json._ import net.liftweb.json.Serialization.write case class Person(name: String, address: Address) case class Address(city: String, state: String) object LiftJsonTest extends App { val p = Person("Alvin Alexander", Address("Talkeetna", "AK")) // create a JSON string from the Person, then print it implicit val formats = DefaultFormats val jsonString = write(p) println(jsonString) }
This code creates a JSON string from the Person instance, and prints it. When you run the project with the sbt run command, you’ll see the following JSON output:
{"name":"Alvin Alexander","address":{"city":"Talkeetna","state":"AK"}}
Gson solution
To demonstrate the Gson library, follow similar steps. Create an empty SBT test project, then download the Gson JAR file from the Gson website, and place it in your project’s lib directory.
In the root directory of the project, create a file named GsonTest.scala with these contents:
import com.google.gson.Gson case class Person(name: String, address: Address) case class Address(city: String, state: String) object GsonTest extends App { val p = Person("Alvin Alexander", Address("Talkeetna", "AK")) // create a JSON string from the Person, then print it val gson = new Gson val jsonString = gson.toJson(p) println(jsonString) }
In a manner similar to the first example, this code converts a Person
instance to a JSON string and prints the string. When you run the project with sbt run
, you’ll see the same output as before:
{"name":"Alvin Alexander","address":{"city":"Talkeetna","state":"AK"}}
Discussion
The Lift-JSON project is a subproject of the Lift Framework, which is a complete Scala web framework. Fortunately the library has been created as a separate module you can download and use on its own.
In addition to working with simple classes, it works well with Scala collections. The following example shows how to generate JSON strings from a simple Scala Map
:
import net.liftweb.json.JsonAST import net.liftweb.json.JsonDSL._ import net.liftweb.json.Printer.{compact,pretty} object LiftJsonWithCollections extends App { val json = List(1, 2, 3) println(compact(JsonAST.render(json))) val map = Map("fname" -> "Alvin", "lname" -> "Alexander") println(compact(JsonAST.render(map))) }
That program prints the following output:
[1,2,3] {"fname":"Alvin","lname":"Alexander"}
When communicating with other computer systems you’ll want to use the compact method as shown, but when a human needs to look at your JSON strings, use the pretty
method instead:
println(pretty(JsonAST.render(map)))
This changes the map
output to look like this:
{ "fname":"Alvin", "lname":"Alexander" }
The Lift-JSON examples in this recipe work well for either objects or collections, but when you have an object that contains collections, such as a Person
class that has a list of friends defined as List[Person]
, it’s best to use the Lift-JSON DSL. This is demonstrated in Recipe 15.2.
Gson is a Java library that you can use to convert back and forth between Scala objects and their JSON representation. From the Gson documentation:
“There are a few open-source projects that can convert Java objects to JSON. However, most of them require that you place Java annotations in your classes; something that you can not do if you do not have access to the source-code. Most also do not fully support the use of Java Generics. Gson considers both of these as very important design goals.”
I used Gson to generate JSON for a while, but because it’s written in Java, it has a few issues when trying to work with Scala collections. One such problem is demonstrated in Recipe 15.2.
See Also
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |