Groovy json string empty - json

I am working with SoapUI and are really new to this. I am supposed to make a few REST tests, a lot of them have to do with dynamic resources so I have to read some json results on runtime. This works fine the first time I do it:
...
def response = context.expand('${Get ContractModels#Response}')
def slurper = new JsonSlurper().parseText(response)
for (i in slurper.ContractModels){
testRunner.testCase.testSteps["ContractModelOptionStep"].setPropertyValue("id",sprintf('%d',i.ContractModelID));
testRunner.runTestStepByName("ContractModelOptionStep")
def innerResponse = context.expand('${Get ContractModelOptionStep#Response}')
log.info(response)
log.info(innerResponse)
def innerSlurper = new JsonSlurper().parseText(innerResponse);
...
}
This works well up to the last line, where it tells me The JSON input text should neither be null nor empty. Thanks to the log.info I found out the JSON Strong of innerResponse is actually empty. Now my problem is I have no clue why, runTestStepByName works perfectly fine and gives the expected response.
Cheers

In these two lines:
testRunner.runTestStepByName("ContractModelOptionStep")
def innerResponse = context.expand('${Get ContractModelOptionStep#Response}')
the name of the test step does not match! Try:
def innerResponse = context.expand('${ContractModelOptionStep#Response}')

Related

Need help on Groovy Script

I am trying to remove double quotes from the Value of 'version' but, not able to do that with the following groovy codes. Please help me resolving this.
Source JSON:
{"version":"1",
"code":'',
"eccQuoteExternalQuoteId":'100000136',
"reasonForRejection":'',
"rejectionCode":'',
"state":{"code":'SOX_APP',"integrationKey":'Approve'},
"integrationKey":''}
Groovy Script:
def Message processData(Message message) {
//Body
def body = message.getBody(String.class);
def jsonSlurper = new JsonSlurper()
def list = jsonSlurper.parseText(body)
list.each{
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
}
def jsonOP = JsonOutput.toJson(list)
message.setBody(jsonOP)
return message;
}
Replace
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
with
it.version=it.get("version").toString().toInteger();
see the ref toInteger.
Your json is incorrect because there are single quotes used for some values. However you could try LAX parser to ignore this issue.
def jsonSlurper = new JsonSlurper().setType(JsonParserType.LAX)
If the json from question is coming through the message body then just change
list.each{
it.version=Integer.parseInt(it.get("version").toString().replace(" ",""));
}
To
list.version = list.version as Integer
#daggett is right, you can do like he said.
It seems that the value of that object is a string, not a problem of quotes.
You can check the class of any the object with:
println(it.version.getClass())
if it's a string you can change it in various ways but if its a string you could simply use the below - I'm putting it in more lines just for better visibility but the result is the same as the inline from daggett
def newInt = it.version.toInteger()
it.version = newInt
There are other ways to do the same thing if you really need to convert it.
here a guide:
https://www.baeldung.com/groovy-convert-string-to-integer
Maybe changing the value from string to int in that class creating the JSON is the best way to go.

Unable to convert into pretty string in groovy

I am making a curl call to rest api visa curl in groovy. Response is coming fine but the response is very large, it is a 17MB of data, following is my script :
def converter = "curl.......'"
def initialSize = 4096
def out = new ByteArrayOutputStream(initialSize)
def err = new ByteArrayOutputStream(initialSize)
def process = [ 'bash', '-c', converter].execute()
process.consumeProcessOutput(out, err)
process.waitFor()
Curl response is coming fine, when I print response on console ,store in variable out, it gives response data where it is not neat json as I see some "/n" characters. When I write this to file then I dont see any new line and neat json, all I see data in one line in key value format.
{"key1":"value1","key2":"value2",} in one huge line only
This is when i view in sublime. Now I want to convert this to pretty json and write neatly into file.I tried following to approaches but both prints empty ({ }) in console and in file.
def json = JsonOutput.toJson(out)
println new JsonBuilder(out).toPrettyString()
What did I miss?
I am trying to use groovy libraries only.
UPDATE:
As i try to debug, i found that it may be because all JSON parsers expect string but my output is ByteArrayOutputStream. But now how can I convert the out to string ? I tried out.toString and out.text, it does not work.
Use StringWriter instead of ByteArrayOutputStream
Then JsonOutput.prettyPrint( stringWriter.toString() )

How can I create a two-element object with Groovy's JsonBuilder?

In my Groovy code, I've got two variables declared:
results is an array of maps. It contains a list of rows returned from a SQL query.
overall is a map. It represents a single row of a separate SQL query.
I want to combine these two variables into one and output the whole thing as JSON. In the end, I want it to look something like this:
{"data":[{"results":"array"}],"overall":{"overall":"map"}}
Here's the code I'm trying to use, but it doesn't work:
def json = new groovy.json.JsonBuilder()
def finalJSON = json {
data results
overall overall
}
return json.toString()
But this doesn't work... it throws the following exception:
groovy.lang.MissingPropertyException: No such property: call for class: groovy.sql.GroovyRowResult
I can verify that both variables results and overall have the correct data in them. I guess I'm just not understanding the syntax for JsonBuilder.
Find possible solutions below:
import groovy.json.*
def r = [[l:1],[l:2]]
def o = [over:1,all:2]
def json = new JsonBuilder()
json {
data r
overall o
}
println json.toPrettyString()
def m = [data: r, overall: o]
println JsonOutput.prettyPrint(JsonOutput.toJson(m))
Okay, I figured it out. Groovy's kind of stupid in that you apparently cannot use the same variable name for the value as the key you're assigning. So the real trouble was with the line that read:
overall overall
I changed that variable to overallData and everything started working.

Groovy JsonSlurper Issue involving commas in JSON

I have some JSON coming into my controller, call it params.formData, it looks like this:
'{"year":"2014","resource":["Smith, John","Foo, Bar"]}'
My code to parse it:
....
def slurper = new JsonSlurper()
def data = slurper.parseText(params.formData)
...
data looks like:
[resource:["Smith", "John", "Foo", "Bar"], year:"2014"]
Notice that there were two JSON entries, and the parser made it into an array of four entries. I want it to look like this:
[resource:["Smith, John", "Foo, Bar"], year:"2014"]
Does anyone know how to handle this situation?
I don't think it does.
assert data.resource.size() == 2
Should prove me right ;-)
My guess is the output of printing data:
[resource:[Smith, John, Foo, Bar], year:2014]
Confused things. It looks like 4, but it's 2
I can't reproduce this behaviour. Run this code in the Groovy console
import groovy.json.JsonSlurper
def json = '{"resource":["Smith, John","Foo, Bar"]}'
def slurper = new JsonSlurper()
def data = slurper.parseText(json)
assert data.resource.size() == 2
The assertion passes, indicating that there are 2 entries. Why do you think there are four?
Definitely a Map rendering "optical illusion"
data.resource.each {
println it
}
Smith, John
Foo, Bar

How to get Slurpable data from REST client in Groovy?

I have code that looks like this:
def client = new groovyx.net.http.RESTClient('myRestFulURL')
def json = client.get(contentType: JSON)
net.sf.json.JSON jsonData = json.data as net.sf.json.JSON
def slurper = new JsonSlurper().parseText(jsonData)
However, it doesn't work! :( The code above gives an error in parseText because the json elements are not quoted. The overriding issue is that the "data" is coming back as a Map, not as real Json. Not shown, but my first attempt, I just passed the parseText(json.data) which gives an error about not being able to parse a HashMap.
So my question is: how do I get JSON returned from the RESTClient to be parsed by JsonSlurper?
The RESTClient class automatically parses the content and it doesn't seem possible to keep it from doing so.
However, if you use HTTPBuilder you can overload the behavior. You want to get the information back as text, but if you only set the contentType as TEXT, it won't work, since the HTTPBuilder uses the contentType parameter of the HTTPBuilder.get() method to determine both the Accept HTTP Header to send, as well was the parsing to do on the object which is returned. In this case, you need application/json in the Accept header, but you want the parsing for TEXT (that is, no parsing).
The way you get around that is to set the Accept header on the HTTPBuilder object before calling get() on it. That overrides the header that would otherwise be set on it. The below code runs for me.
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.6')
import static groovyx.net.http.ContentType.TEXT
def client = new groovyx.net.http.HTTPBuilder('myRestFulURL')
client.setHeaders(Accept: 'application/json')
def json = client.get(contentType: TEXT)
def slurper = new groovy.json.JsonSlurper().parse(json)
The type of response from RESTClient will depend on the version of :
org.codehaus.groovy.modules.http-builder:http-builder
For example, with version 0.5.2, i was getting a net.sf.json.JSONObject back.
In version 0.7.1, it now returns a HashMap as per the question's observations.
When it's a map, you can simply access the JSON data using the normal map operations :
def jsonMap = restClientResponse.getData()
def user = jsonMap.get("user")
....
Solution posted by jesseplymale workes for me, too.
HttpBuilder has dependencies to some appache libs,
so to avoid to add this dependencies to your project,
you can take this solution without making use of HttpBuilder:
def jsonSlurperRequest(urlString) {
def url = new URL(urlString)
def connection = (HttpURLConnection)url.openConnection()
connection.setRequestMethod("GET")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("User-Agent", "Mozilla/5.0")
new JsonSlurper().parse(connection.getInputStream())
}