Groovy JSON is missing quotes around strings

4k views Asked by At

(Groovy Version: 2.4.16 JVM: 11.0.8 Vendor: Debian OS: Linux)

My bash shell script outputs a JSON string that looks like this (without the "sout: "):

sout: {"vms":["Jenkins","UbuntuRunner"]}

Which I use as input to this Groovy code:

    def sout = new StringBuilder()
    def serr = new StringBuilder()

    // translate JSON to List
    def soutJson = new JsonSlurper().parseText(sout.toString())
    log.append("sout: " + sout + "\n")
    log.append("serr: " + serr + "\n")
    log.append("soutJson: " + soutJson + "\n")
    
    def List myList = soutJson.vms
    log.append("myList: " + myList + "\n")
    log.append("myList[0]: " + myList[0] + "\n")
    log.append("myList[1]: " + myList[1] + "\n")
    log.append("myList.size(): " + myList.size() + "\n")

I expect the output to include quotation marks, like this:

soutJson: ["vms":["Jenkins", "UbuntuRunner"]]
myList: ["Jenkins", "UbuntuRunner"]
myList[0]: "Jenkins"
myList[1]: "UbuntuRunner"
myList.size(): 2

But what is actually output is missing the quotes:

soutJson: [vms:[Jenkins, UbuntuRunner]]
myList: [Jenkins, UbuntuRunner]
myList[0]: Jenkins
myList[1]: UbuntuRunner
myList.size(): 2

Every example I find of printing a List or elements of the List include quotes. I don't care if these are single or double quotes but the code that later takes myList as input won't work if there are no quotes. And it can't be a string, it must be a List.

How do I retain the quotation marks?

1

There are 1 answers

0
CodeMonkey On

JsonSlurper().parseText() in Groovy with JSON Object as input returns an instance of org.apache.groovy.json.internal.LazyMap class implementing the Map interface. The JSON structure stored in LazyMap is normalized to native Java primitives (not JSON primitives) where String values are treated natively and toString() on Map returns String values as-is with no quotes.

To properly encode JSON output from JsonSlurper use JsonOutput class, but return type of JsonOutput.toJson() is a String.

import groovy.json.JsonOutput
String json = '{ "vms":["Jenkins","UbuntuRunner"] }'
def soutJson = new JsonSlurper().parseText(json)
String jsonOut = JsonOutput.toJson(soutJson)
println jsonOut

Output:

{"vms":["Jenkins","UbuntuRunner"]}

If you want the internal elements of the parsed JSON object to output as JSON then recommend the Gson library.

Example:

import com.google.gson.Gson
import com.google.gson.JsonParser
import com.google.gson.JsonObject
    
String json = '{ "vms":["Jenkins","UbuntuRunner"] }'
def object = JsonParser.parseString(json)
// Or Gson instance and fromJson() method to achieve same result
// def gson = new Gson()
// def object = gson.fromJson(json, JsonObject.class)
println "soutJson: " + object
def myList = object.get('vms')
println "myList: " + myList
println "myList[0]: " + myList[0]

Output:

soutJson: {"vms":["Jenkins","UbuntuRunner"]}
myList: ["Jenkins","UbuntuRunner"]
myList[0]: "Jenkins"