This is something I’ve had to look up a few times, so I figured it’s time to write up something to ease the next time a bit.
First we need to include the Play JSON library itself to build.sbt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name := """minimal-scala""" | |
version := "1.0" | |
scalaVersion := "2.11.7" | |
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.5.13" |
Using case classes seems to be the most used method of holding data to be encoded in JSON. So the next step is to configure out case class InventoryItem for reading and writing (decoding / encoding) into JSON with a companion object.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object InventoryItem { | |
implicit val inventoryItemWrites: Writes[InventoryItem] = ( | |
(JsPath \ "name").write[String] and | |
(JsPath \ "serialNumber").write[String] and | |
(JsPath \ "value").write[Float] | |
)(unlift(InventoryItem.unapply)) | |
implicit val inventoryItemReads: Reads[InventoryItem] = ( | |
(JsPath \ "name").read[String] and | |
(JsPath \ "serialNumber").read[String] and | |
(JsPath \ "value").read[Float] | |
)(InventoryItem.apply _) | |
} | |
case class InventoryItem(name: String, serialNumber: String, value: Float) {} |
I’m using an example where we write a list of InventoryItems into JSON. Play JSON knows how to handle Lists automatically so no configuration is needed for that.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object WritingJson extends App { | |
var inventory = List[InventoryItem]() | |
inventory = inventory :+ InventoryItem("Name", "SR-001", 33.0) | |
val json = Json.toJson(inventory) | |
println(Json.stringify(json)) | |
} |
List of IntentoryItems would like something like this in JSON.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"name": "Item", | |
"serialNumber": "asdsad", | |
"value": 22 | |
}, | |
{ | |
"name": "Another Item", | |
"serialNumber": "SRS-001", | |
"value": 33 | |
} | |
] |
Reading JSON is from a string is a bit more involved than writing it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ReadingJson extends App { | |
var inventory: List[InventoryItem] = List() | |
val itemJsonString = Source.fromFile("D:\\Path\\To\\My.json").mkString | |
val json = Json.parse(itemJsonString) | |
json.validate[List[InventoryItem]] match { | |
case s: JsSuccess[List[InventoryItem]] => inventory = s.get | |
case e: JsError => println("Oh dog, what done") | |
} | |
} |