Groovy OkHttpBuilder with GET Method - getting groovy.json.JsonException - groovy

Hi I'm using Groovy HTTPBuilder to make a GET call with request body similar like this:
def obj = [:]
// add the data in map - obj
def http = OkHttpBuilder.configure {
request.uri = "URL"
request.uri.path = "/path"
request.headers.put("Authorization", "token value")
request.cookie("fingerprint", "fingerprint value")
request.accept ="application/json"
request.headers.put("Content-Type", "application/json;")
def jsonBody = JsonOutput.toJson(obj)
request.body = jsonBody
response.failure { FromServer fromServer, Object body ->
assertHttpFailure(fromServer, body)
}
}
http.get()
But, getting an groovy.json.JsonException with below details
Unable to determine the current character, it is not a string, number, array, or object
The current character read is 'R' with an int value of 82
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 0
Required request body is missing: public org.springframework.http.ResponseEntity<java.util.List
Any suggestions ? why request body says missing

Related

How to test for Empty array value in Unirest json Response

I have the following code snipet used in Jira Script Runner cloud
String _userId
def result = get(graph_base_user_url + "?")
.header("Authorization","Bearer " + AuthToken )
.queryString("\$filter","mail eq '$userEmail'")
.asJson()
if (result.getStatus().toString() =="200")
{
**if (result.getBody().value){ // <<<<< is Value is not empty ???
_userId=result.getBody().value[0].id
}**
else
_userId="-1" // user does not exist
}
// user ID not found : error 404
if (result.getStatus().toString()=="404")
_userId="User not found"
This code is returning in the result.getBody() the following output
{"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users","value":[]}
What I am trying to achieve is to test if the value array of the response is empty or not and if not empty I need to fetch the first element item as value[0].Id, but I could not get it correctly
How can I define my code in BOLD above to perform my correct test ?
Error I get from my code is : " Value is not a property of JsonNode object
Thanks for help
regards
from official doc http://kong.github.io/unirest-java/#responses
String result = Unirest.get("http://some.json.com")
.asJson()
.getBody()
.getObject()
.getJSONObject("car")
.getJSONArray("wheels")
.get(0)
so, something like this should work for you:
def a = result.getBody().getObject().getJSONArray("value")
if(a.length()>0) _userId = a.get(0).get("id")

How to catch null value on http response

I have the following code method which is used to test for an existing user in MSGraph API
public String getGuestUserId(String AuthToken,String userEmail){
String _userId
def http = new HTTPBuilder(graph_base_user_url + "?")
http.request(GET) {
requestContentType = ContentType.JSON
//uri.query = [ $filter:"mail eq '$userEmail'"].toString()
uri.query=[$filter:"mail eq '$userEmail'"]
headers.'Authorization' = "Bearer " + AuthToken
response.success = { resp, json ->
//as the retunr json alue is an array collection we need to get the first element as we request all time one record from the filter
**_userId=json.value[0].id**
}
// user ID not found : error 404
response.'404' = { resp ->
_userId = 'Not Found'
}
}
_userId
}
This method works fine when the user is existing and will return properly from the success response the user ID property.
The issue I get is that if the user is not existing, the ID field is not existing either and the array is empty.
How can I handle efficiently that case and return a meaning full value to the caller like "User Does not exist"
I have try a catch exception in the response side but seems doe snot to work
Any idea how can I handle the test like if the array[0] is empty or does not contains any Id property, then return something back ?
Thanks for help
regards
It seems to be widely accepted practice not to catch NPE. Instead, one should check if something is null.
In your case:
You should check if json.value is not empty
You also should check if id is not null.
Please also note that handling exceptions in lambdas is always tricky.
You can change the code to:
http.request(GET) {
requestContentType = ContentType.JSON
uri.query=[$filter:"mail eq '$userEmail'"]
headers.'Authorization' = "Bearer " + AuthToken
if (json.value && json.value[0].id) {
response.success = { resp, json -> **_userId=json.value[0].id** }
} else {
// Here you can return generic error response, like the one below
// or consider more granular error reporting
response.'404' = { resp -> _userId = 'Not Found'}
}
}

Httpbuilder put examples for sending multiple query params groovy

I am using Httpbuilder 0.7.1 and groovy 1.8 to invoke the rest call.
I need to send the mutiple values for the same query parameter but it is not working.
I need to send values as below
https:///?action=test&group=grp1&group=grp2
I have tried with the code below and it is working as expected.
Map query = [:]
Map headerMap = [:]
headerMap["Accept"] = 'application/json'
headerMap["Authorization"] = authtoken
def groupsListArray=[]
if (group.contains(",")) {
def groupsList = group.split(",");
for ( singlegroup in groupsList) {
groupsListArray.add(singlegroup.toString())
}
query.put("group",groupListArray)
}
else{
query.put("group",group)
}
def http = new HTTPBuilder(baseUrl)
http.request(method) { req ->
uri.path = path
uri.query = query
headerMap.each { key, value ->
headers."${key}" = "${value}" }
}
Is there any other way, we can send multiple values for the same query parameter with httpbuilder?
Okie, the issue has been identified with the REST service and there is no issue with this code.Thanks for the help

Get response body on success in HTTPBuilder-NG

I'm trying to use Httpbuilder-NG in the Gradle script of an Android Studio project. The script uploads some files to a web server for validation, the server responds with 'ok' or the name of the file that did not validate.
I am trying
response.success { FromServer fs, Object body ->
println "Success: ${fs.statusCode}, Text is: ${body}, Properties are: ${body.properties}"
}
and the result is always:
Success: 200, Text is: [102, 105, 108, 101], Properties are: [class:class [B, length:4]
Note it is a 4-element array, not a text string. And the array stays the same whether the server returns 'ok' or something else. I recognize my server may be returning something non-standard but it works fine in Postman.
I have also tried
response.success { FromServer fs, Object body ->
println "has body = ${fs.hasBody}"
println "content type = ${fs.contentType}"
println "charset = ${fs.charset}"
println "files uploaded, result = ${fs.reader.text}"
//println "Success: ${fs.statusCode}, Text is: ${body}, Properties are: ${body.properties}"
}
and the result is always
has body = true
content type = text/html
charset = UTF-8
files uploaded, result =
i.e. a blank string where the body should be.
fs.hasBody returns true
Any help would be appreciated.
def httpBin = configure {
request.uri = 'http://groovy-lang.org/processing-xml.html'
}
def result = httpBin.get() {
response.success { fromServer,body ->
body
}
}
assert result instanceof groovy.util.slurpersupport.NodeChild
println result
Code snippet above returns all text inside <body> tag of this web page http//...processing-xml
To narrow your result, you need to parse groovy.util.slurpersupport.NodeChild futher.

Spock: check the query parameter count in URI

I have just started with spock. I have one functionality. where the java function makes an http call. As per functionality, the URI used in http call, must contain "loc" parameter and it should be only once.
I am writing Spock test case. I have written below snippet.
def "prepareURI" () {
given: "Search Object"
URI uri = new URI();
when:
uri = handler.prepareURI( properties) // it will return URI like http://example.com?query=abc&loc=US
then:
with(uri)
{
def map = uri.getQuery().split('&').inject([:]) {map, kv-> def (key, value) = kv.split('=').toList(); map[key] = value != null ? URLDecoder.decode(value) : null; map }
assert map.loc != null
}
}
From above snippet, my 2 tests got passed like
It should be exists
It should not be null
I want to check the count of "loc" query parameter. It should be passed exactly once. With map as above, If I pass "loc" parameter twice, map overrides the old value with 2nd one.
Does any one knows, how to access the query parameters as list, and in list I want to search the count of Strings which starts with "loc"
Thanks in advance.
Perhaps an example would be the best start:
def uri = new URI('http://example.com?query=abc&loc=US')
def parsed = uri.query.tokenize('&').collect { it.tokenize('=') }
println "parsed to list: $parsed"
println "count of 'loc' params: " + parsed.count { it.first() == 'loc' }
println "count of 'bob' params: " + parsed.count { it.first() == 'bob' }
println "count of params with value 'abc': " + parsed.count { it.last() == 'abc' }
prints:
$ groovy test.groovy
parsed to list: [[query, abc], [loc, US]]
count of 'loc' params: 1
count of 'bob' params: 0
count of params with value 'abc': 1
the problem, as you correctly noted, is that you can not put your params into a map if your intent is to count the number of params with a certain name.
In the above, we parse the params in to a list of lists where the inner lists are key, value pairs. This way we can call it.first() to get the param names and it.last() to get the param values. The groovy List.count { } method lets us count the occurences of a certain item in the list of params.
As for your code, there is no need to call new URI() at the beginning of your test as you set the value anyway a few lines down.
Also the with(uri) call is unnecessary as you don't use any of the uri methods without prefixing them with uri. anyway. I.e. you can either write:
def uri = new URI('http://example.com?query=abc&loc=US')
def parsed = uri.query.tokenize('&').collect { it.tokenize('=') }
or:
def uri = new URI('http://example.com?query=abc&loc=US')
uri.with {
def parsed = query.tokenize('&').collect { it.tokenize('=') }
}
(note that we are using query directly in the second example)
but there is not much point in using with if you are still prefixing with uri..
The resulting test case might look something like:
def "prepareURI"() {
given: "Search Object"
def uri = handler.prepareURI( properties) // it will return URI like http://example.com?query=abc&loc=US
when:
def parsed = query.tokenize('&').collect { it.tokenize('=') }
then:
assert parsed.count { it.first() == 'loc' } == 1
}

Resources