# Fetching nested JSON values from session attributes

**URL:** <https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307>\
**Category:** Gatling (Open-Source)\
**Created:** [August 20, 2014, 3:11pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307 "2014-08-20T15:11:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Neil](https://avatars.discourse-cdn.com/v4/letter/n/839c29/32.png) [@Neil](https://community.gatling.io/u/Neil)\
**Post date:** [August 20, 2014, 3:11pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/1 "2014-08-20T15:11:41Z")

</div>

I am trying to parse the following response and do some calculation on id and version .

`

```auto
{
  "result": "SUCCESS",
  "data": [
    {
      "playerId": {
          "id":2,
          "version":1
      },
      "score":200
    }
  ]
}

```

`

Code is

`  
package computerdatabase

import io.gatling.core.Predef.\_  
import io.gatling.http.Predef.\_  
import scala.concurrent.duration.\_  
import io.gatling.jsonpath.\_

class Test1 extends Simulation {

//Global Users  
val userMap = scala.collection.concurrent.TrieMapString, String  
//Randomiser  
val rnd = new scala.util.Random  
val httpConf = http  
.baseURL(“[http://demo1263864.mockable.io/](http://demo1263864.mockable.io/)”) // Here is the root for all relative URLs  
.acceptHeader(“application/json”) // Here are the common headers  
.doNotTrackHeader(“1”)  
.acceptLanguageHeader(“en-US,en;q=0.5”)  
.acceptEncodingHeader(“gzip, deflate”)  
.userAgentHeader(“Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0”)

val headers\_10 = Map(“Content-Type” → “application/json”) // Note the headers specific to a given request

val scn = scenario(“Simple request”)  
.exec(  
http(“If request “)  
.get(“gatling1”)  
.headers(headers\_10)  
.check(jsonPath(”$.result”).is(“SUCCESS”),  
jsonPath("$.data[\*]").ofType[Map[String, Any]].findAll.saveAs(“pList”)))  
.foreach("${pList}", “player”) {  
exec(session =\> {  
val playerMap = session(“player”).as[Map[String, Any]]  
val playerId = playerMap(“playerId”).asInstanceOf[Map[String, Any]]  
val id = playerId(“id”)  
println(id)  
session.set(“playerId”, playerId)  
})  
}

setUp(scn.inject(atOnceUsers(1)).protocols(httpConf))  
}Enter code here…  
`

The line

` `  
val playerId = playerMap(“playerId”).asInstanceOf[Map[String, Any]]

` `

`Errors out with`

` `  
20:36:15.860 [ERROR] i.g.c.a.b.SessionHookBuilder$$anonfun$build$1$$anon$1 - Action anonfunbuild1anon1 crashed on session Some(Session(Simple request,4173992086124673397-0,Map(8d6aa6d4-3c7e-4e8f-b475-db8bfe5094e1 → 0, pList → Vector(Map(playerId → {id=2, version=1}, score → 200)), timestamp.8d6aa6d4-3c7e-4e8f-b475-db8bfe5094e1 → 1408547175843, player → Map(playerId → {id=2, version=1}, score → 200), gatling.http.cookies → CookieJar(Map())),1408547175294,71,OK,List(ExitOnCompleteLoopBlock(8d6aa6d4-3c7e-4e8f-b475-db8bfe5094e1)))), forwarding to the next one  
java.lang.ClassCastException: org.boon.core.value.LazyValueMap cannot be cast to scala.collection.immutable.Map  
at computerdatabase.Test1$$anonfun$1.apply(Test1.scala:34) ~[na:na]  
at computerdatabase.Test1$$anonfun$1.apply(Test1.scala:32) ~[na:na]  
at io.gatling.core.action.SessionHook.executeOrFail(SessionHook.scala:35) ~[gatling-core-2.0.0-RC2.jar:2.0.0-RC2]  
at io.gatling.core.action.Failable$class.execute(Actions.scala:71) ~[gatling-core-2.0.0-RC2.jar:2.0.0-RC2]  
at io.gatling.core.action.SessionHook.execute(SessionHook.scala:28) ~[gatling-core-2.0.0-RC2.jar:2.0.0-RC2]  
at io.gatling.core.action.Action$$anonfun$receive$1.applyOrElse(Actions.scala:29) ~[gatling-core-2.0.0-RC2.jar:2.0.0-RC2]  
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:166) ~[scala-library.jar:na]  
at akka.actor.Actor$class.aroundReceive(Actor.scala:465) ~[akka-actor\_2.10-2.3.4.jar:na]  
at io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:23) ~[gatling-core-2.0.0-RC2.jar:2.0.0-RC2]  
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516) ~[akka-actor\_2.10-2.3.4.jar:na]  
at akka.actor.ActorCell.invoke(ActorCell.scala:487) ~[akka-actor\_2.10-2.3.4.jar:na]  
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238) ~[akka-actor\_2.10-2.3.4.jar:na]  
at akka.dispatch.Mailbox.run(Mailbox.scala:220) ~[akka-actor\_2.10-2.3.4.jar:na]  
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393) [akka-actor\_2.10-2.3.4.jar:na]  
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library.jar:na]  
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library.jar:na]  
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library.jar:na]  
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library.jar:na]  
` `  
`How do I handle `nested maps ?

---

<div class="post-metadata">

**Author:** ![Pierre\_DAL-PRA](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pierre\_DAL-PRA](https://community.gatling.io/u/Pierre_DAL-PRA)\
**Post date:** [August 20, 2014, 3:37pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/2 "2014-08-20T15:37:04Z")

</div>

Ah, this actually looks like a bug…  
Will investigate.

In the mean time, you can still get each value separately :

`  
.check(  
jsonPath("$.result").is(“SUCCESS”),  
jsonPath("$.data.playerId.id").ofType[Seq[Int]].findAll.saveAs(“playerIds”)  
jsonPath("$.data.playerId.version").ofType[Seq[Int]].findAll.saveAs(“playerVersions”)  
)

`

This will save one list of ids and one list of versions in the session, which you can then put back together should you need to :

`  
case class Player(id: Int, version: Int)

.exec(session =\> {  
val playerIds = session(“playerIds”).as[Seq[Int]]  
val playerVersions = session(“playerVersions”).as[Seq[Int]]  
val players = (playerIds, playerVersions).zipped.map(Player.apply))  
session.set(“players”, players)  
})  
`

This last piece of code :

- fetches the two lists from the session

- “zips” the lists, e.g. (_List(1,3), List(2, 4) ==\> List((1,2), (3,4))_

- Builds a list of _Player_ from the previous lists

Hope this helps !

Cheers,

Pierre

---

<div class="post-metadata">

**Author:** ![Neil](https://avatars.discourse-cdn.com/v4/letter/n/839c29/32.png) [@Neil](https://community.gatling.io/u/Neil)\
**Post date:** [August 20, 2014, 3:53pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/3 "2014-08-20T15:53:50Z")

</div>

Thanks Pierre,  
I did think about this individual list workaround . The problem is that my actual JSON format is deeply nested and complex in nature ,so wanted a straight forward way to deal with a block of JSON at a time. Basically the requirement is similar to obtaining those playerIDs whose version is 1. There is an old post which uses some Json library to do so but I wanted to have a loop and filter.

Still I will try this approach.  
Let me know in case you decide to file a bug so that I can follow.

---

<div class="post-metadata">

**Author:** ![Neil](https://avatars.discourse-cdn.com/v4/letter/n/839c29/32.png) [@Neil](https://community.gatling.io/u/Neil)\
**Post date:** [August 21, 2014, 6:15am UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/4 "2014-08-21T06:15:11Z")

</div>

I settled for the following which is similar to Pierre’s code

`  
.check(  
jsonPath("$.result").is(“SUCCESS”),

jsonPath("$.data.playerId.id").findAll.saveAs(“playerIds”)  
jsonPath("$.data.playerId.version").findAll.saveAs(“playerVersions”)  
)

`

Note: casting to as[Seq[Int]] game me error  
`

.exec(session =\> {

val playerIds = session(“playerIds”).as[Vector[String]]  
val playerVersions = session(“playerVersions”).as[Vector[String]]  
playerIds.indices.foreach { i =\>  
if (playerVersions(i) == 1) {  
filteredPlayerIds += playerIds(i)  
}  
}  
})  
`

Anything other than as[Vector[String]] gave me error

---

<div class="post-metadata">

**Author:** ![Pierre\_DAL-PRA](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@Pierre\_DAL-PRA](https://community.gatling.io/u/Pierre_DAL-PRA)\
**Post date:** [August 21, 2014, 1:52pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/5 "2014-08-21T13:52:10Z")

</div>

Hi Neil,

You need to specify that _id_ and _version_ are to be treated as Ints, or they’re saved as Strings.

This works (unfortunately there was a slight error in my previous example) :

`jsonPath("$.data.playerId.id").ofType[Int].findAll.saveAs("playerIds") jsonPath("$.data.playerId.version").ofType[Int].findAll.saveAs("playerVersions")`

Then you can get it back as a _Vector[Int]._

Cheers,

Pierre

---

<div class="post-metadata">

**Author:** ![Till\_Neunast](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@Till\_Neunast](https://community.gatling.io/u/Till_Neunast)\
**Post date:** [April 24, 2016, 5:26am UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/6 "2016-04-24T05:26:11Z")

</div>

Hi,

Though an old thread, I thought I’d post a suggestion as I’ve come across a similar situation.

I found that the Gatling JsonPath implementation (import io.gatling.jsonpath.JsonPath) with its filter conditions could work here (at least for simple filter logic):

`  
jsonPath("$.data[?(@.playerId.version == 1)]").ofType[Any].findAll.saveAs(“filteredPlayers”)

`  
Then you can do what you like with the saved player objects later on.

Or, if you’re only interested in the ids, to get your Vector[Int]:

`  
jsonPath("$.data[?(@.playerId.version == 1)]").ofType[Any].findAll  
.transform(\_.map(JsonPath.query("$.playerId.id", \_).right.get.next.asInstanceOf[Int]))  
.saveAs(“filteredPlayerIds”)

`

However, if your filter expression is too complex for JsonPath, you could do:

`jsonPath("$.data[*]").ofType[Any].findAll .transform(_.filter(JsonPath.query("$.playerId.version", _).right.get.next.asInstanceOf[Int] == 1)) .saveAs("players")`

Anyhow, the transform step eliminates the need for your forEach loop.

HTH,  
Till

---

<div class="post-metadata">

**Author:** ![slandelle](https://dub1.discourse-cdn.com/flex013/user_avatar/community.gatling.io/slandelle/32/4_2.png) [@slandelle](https://community.gatling.io/u/slandelle)\
**Post date:** [April 26, 2016, 9:08pm UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/7 "2016-04-26T21:08:14Z")

</div>

Yep, you can do that.  
But you’d better compile your paths once and for all if they’re static, instead of over and over again.

---

<div class="post-metadata">

**Author:** ![Manohari](https://avatars.discourse-cdn.com/v4/letter/m/96bed5/32.png) [@Manohari](https://community.gatling.io/u/Manohari)\
**Post date:** [August 8, 2016, 10:31am UTC](https://community.gatling.io/t/fetching-nested-json-values-from-session-attributes/1307/8 "2016-08-08T10:31:02Z")

</div>

hi,  
{“id”:30,“result”:{“moreRows”:0,“landmarkList”:[{“id”:“40542263”,“lastUpdate”:“2016-07-15 16:27:45”},{“id”:“40542309”,“lastUpdate”:“2016-07-15 16:27:45”},{“id”:“47891637”,“lastUpdate”:“2016-07-15 16:27:45”},{“id”:“47891639”,“lastUpdate”:“2016-07-15 16:27:45”},{“id”:“40542383”,“lastUpdate”:“2016-07-15 16:27:45”}]}}

how can i get id’s from the above json

Thanks in Advance
