Search code examples
scalagatlingjsonpath

How to read a JSON file into a Map, using Scala


How can I read a JSON file into a Map, using Scala. I've been trying to accomplish this but the JSON I am reading is nested JSon and I have not found a way to easily extract the JSON into keys because of that. Scala seems to be wanting to also convert the nested JSON String into an object. Instead, I want the nested JSON as a String "value". I am hoping someone can clarify or give me a hint on how I might do this.

My JSON source might look something like this:

{
  "authKey": "34534645645653455454363",
  "member": {
    "memberId": "whatever",
    "firstName": "Jon",
    "lastName": "Doe",
    "address": {
      "line1": "Whatever Rd",
      "city": "White Salmon",
      "state": "WA",
      "zip": "98672"
    },
    "anotherProp": "wahtever",
  }
}

I want to extract this JSON into a Map of 2 keys without drilling into the nested JSON. Is this possible? Once I have the Map, my intention is to add the key-values to my POST request headers, like so:

val sentHeaders = Map("Content-Type" -> "application/javascript", 
   "Accept" -> "text/html", "authKey" -> extractedValue,
   "member" -> theMemberInfoAsStringJson)
http("Custom headers")
.post("myUrl")
.headers(sentHeaders)

Solution

  • Since the question is tagged 'gatling', behind the curtains this lib depends on Jackson/fasterxml for JSON processing, so we can make use of it.

    There is no way to retrieve a nested structured part of JSON as String directly, but with very few additional code the result can still be achieved.

    So, having the input JSON:

    val json = """{
                 |  "authKey": "34534645645653455454363",
                 |  "member": {
                 |    "memberId": "whatever",
                 |    "firstName": "Jon",
                 |    "lastName": "Doe",
                 |    "address": {
                 |      "line1": "Whatever Rd",
                 |      "city": "White Salmon",
                 |      "state": "WA",
                 |      "zip": "98672"
                 |    },
                 |    "anotherProp": "wahtever"
                 |  }
                 |}""".stripMargin
    

    A Jackson's ObjectMapper can be created and configured for use in Scala:

    // import com.fasterxml.jackson.module.scala.DefaultScalaModule
    
    val mapper = new ObjectMapper().registerModule(DefaultScalaModule)
    

    To parse the input json easily, a dedicated case class is useful:

    case class SrcJson(authKey: String, member: Any) {
      val memberAsString = mapper.writeValueAsString(member)
    }
    

    We also include val memberAsString in it, which will contain our target JSON string, obtained through a reverse conversion from initially parsed member which actually is a Map.

    Now, to parse the input json:

    val parsed = mapper.readValue(json, classOf[SrcJson])
    

    The references parsed.authKey and parsed.memberAsString will contain the researched values.