arraysgroovyjsonbuilder

JSON with array and non-array data with Groovy JsonBuilder


I need to create a JSON string in my Groovy script which has some elements that are array and some which are not. For example the below..

 {
 "fleet": {
   "admiral":"Preston",
   "cruisers":  [
      {"shipName":"Enterprise"},
      {"shipName":"Reliant"}
   ]
  }
}

I found this post but the answers either didn't make sense or didn't apply to my example.

I tried the below in code...

 def json = new groovy.json.JsonBuilder()
 def fleetStr = json.fleet {
         "admiral" "Preston"
         cruisers {
            {shipName: "[Enterprise]"},  {shipName: "[Reliant]"}
       }
   }

But it gives an exception...

 Ambiguous expression could be either a parameterless closure expression or an isolated open code block

Solution

  • In Groovy, the {} syntax is used for closures. For objects in JSON, you want to use the map syntax [:], and for lists, the list syntax []:

    def json = new groovy.json.JsonBuilder()
    def fleetStr = json.fleet {
        "admiral" "Preston"
        cruisers( [
            [shipName : "[Enterprise]"],
            [shipName: "[Reliant]"]
        ])
    }
    
    assert json.toString() == 
        '{"fleet":{"admiral":"Preston","cruisers":[{"shipName":"[Enterprise]"},{"shipName":"[Reliant]"}]}}'
    

    Update: as per your follow-up, you need to use the same list syntax [] outside the "[Enterprise]" and "[Reliant]" strings:

    def json = new groovy.json.JsonBuilder()
    def fleetStr = json.fleet {
        "admiral" "Preston"
        cruisers( [
            [shipName : ["Enterprise"]],
            [shipName: ["Reliant"]]
        ])
    }
    
    assert json.toString() == 
        '{"fleet":{"admiral":"Preston","cruisers":[{"shipName":["Enterprise"]},{"shipName":["Reliant"]}]}}'