Update: I've been notified the json4s
has some fairly severe and public DoS issues.
Andriy Plokhotnyuk@aplokhotnyuk@Fbyrne CAUTION: json4s is vulnerable under DoS/DoW attacks which exploit hash collision vulnerabilities of Scala's HashMap or parsing vulnerabilities of Java's BigInteger/BigDecimal values: github.com/json4s/json4s/…19:46 PM - 20 Oct 2019
I'll make another post exploring this basic case using some of the libraries recommended in the thread.
I had been searching for an easy way to work with JSON in Scala. Most libraries expect the user wants to create advanced encoding and decoding functionality; therefore making them a bit difficult to jump into.
Fortunately I found this StackOverflow post that showed how to represent JSON using basic Scala data types such as Map
, List
, and String
:
For example, I have this Map value in Scala:
val m = Map(
"name" -> "john doe",
"age" -> 18,
"hasChild" -> true,
"childs" -> List(
Map("name" -> "dorothy", "age" -> 5, "hasChild" -> false),
Map("name" -> "bill", "age" -> 8, "hasChild" -> false)
)
)
I want to convert…
The really big takeaway is that json4s
performs recursive JSON encoding/decoding with fundamental Scala types where most basic libraries will only encode/decode one level deep.
Getting started is fairly easy.
1. Follow the installation steps for json4s
.
-
Add the following to your
build.sbt
file:
// Change 3.6.7 to whatever the latest version is on Maven Central libraryDependencies += "org.json4s" %% "json4s-native" % "3.6.7"
2. Decode JSON
import org.json4s._
import org.json4s.native.JsonMethods._
object DecodeJSON extends App {
val jsonString =
"""
|{
| "hello": "world",
| "data": {
| "number": 12,
| "lie": false
| }
|}
|""".stripMargin
val decoded = parse(jsonString)
println(decoded)
// JObject(List((hello,JString(world)),(data,JObject(List((number,JInt(12)), (lie,JBool(false)))))))
}
- Notice the output uses special wrapper classes to represent the JSON data types and structure. The full list is found here.
3. Encoding JSON
Decoding recursively from Maps and Lists is possible as shown in the Stackoverflow post, but json4s
provides a domain specific language (DSL) for creating JSON.
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
object Hello extends App {
// ~ is part of the json4s scala DSL
// it means these fields belong on the same Object level.
// It corresponds directly to a JSON comma (,).
val jsonScala = ("hello" -> "world") ~
("data" ->
("number" -> 12) ~
("lie" -> false)
)
println(compact(render(jsonScala)))
// {"hello":"world","data":{"number":12,"lie":false}}
}
Conclusion
There are many JSON libraries for Scala out there, but json4s
excels for quick and dirty projects involving dynamic JSON and simple types. Also, I'm really new to Scala so if you have a library you enjoy for working with JSON please share!
Top comments (1)
CAUTION: json4s is vulnerable under DoS/DoW attacks which exploit hash collision vulnerabilities of Scala's HashMap or parsing vulnerabilities of Java's BigInteger/BigDecimal values:
github.com/json4s/json4s/issues?ut...
Please consider to use more safe and efficient JSON parsers for Scala, like:
github.com/sirthias/borer
github.com/circe/circe
github.com/pathikrit/dijon
github.com/plokhotnyuk/jsoniter-scala