Get html body from response in groovy - html

I'm trying to see if a specific string exists in an html page but I can't seem to find an easy way to get the string that represents the body.
I've attempted:
http.request(Method.GET, { req ->
uri.path = '/x/app/main'
response.success = { resp, reader ->
assert resp.status == 200
println reader.text.startsWith('denied')
}
response.failure = { resp ->
fail("Failure reported: ${resp.statusLine}")
}
})
but reader.text is a NodeChildren object.
How do I get the html (or more specifically, the contexts of the body) as a string?

You can get an input stream directly off of the response. Try this:
http.request(Method.GET, { req ->
uri.path = '/x/app/main'
response.success = { resp ->
assert resp.status == 200
println resp.entity.content.text.startsWith('denied')
}
response.failure = { resp ->
fail("Failure reported: ${resp.statusLine}")
}
})

Related

Get values from a JSON response in Groovy

I have a groovy script, it does an easy API call, and I am getting as response a JSON body.
How can I get, from the JSON body, a single value, and use it as a variable?
newRelease.request(GET) { req ->
requestContentType = ContentType.JSON
headers.'X-Octopus-ApiKey' = 'API-xxx'
response.success = { resp, JSON ->
return JSON
}
response.failure = { resp ->
return "Request failed with status ${resp.status}"
}
}
and this is the response
[DeploymentProcessId:deploymentprocess-Projects-370, LastReleaseVersion:null, NextVersionIncrement:0.0.41, VersioningPackageStepName:null, Packages:[], Links:[Self:/api/Spaces-1/deploymentprocesses/deploymentprocess-Projects-370/template]]
So what I am trying to extract is the NextVersionIncrement.
Any idea?

Grails httpbuilder json response

Having a few issues with the response handling of my httpbuilder post and json
within my service I have:
def jsonDataToPost = '{"accountNumber" : ' + accNo + ',"accountName" : ' + accName + '}'
def http = new HTTPBuilder('https://myurl.com/dataInput')
def jsonResponse
http.auth.basic ('username','password')
http.request(POST, ContentType.JSON) {
headers.'Content-Type' = 'application/json'
body = jsonDataToPost
response.success = { json ->
println("Success")
jsonResponse = json
}
response.failure = { json ->
println("Fail")
jsonResponse = json
}
}
firstly for some reason the code actually skips out rather than completing and so I'm not getting the jsonReponse I'm after but I can't figure out why? If I reponse my response.success/fail and I post correct data my json post works but again I still get no json back
Try this,
def requestData = [foo:bar]
http.request(POST, ContentType.JSON) {
headers.'Content-Type' = 'application/json'
body = (requestData as JSON).toString()
response.success = { resp, reader ->
println("Success")
jsonReponse = reader.text
}
response.failure = { resp, reader ->
println("Failed, status: " + resp.status)
jsonReponse = reader.text
}
}
If you're using Grails 3.x you can use http-builder-ng
https://http-builder-ng.github.io/http-builder-ng

groovy: how to catch exceptions on AsyncHttpBuilder

i'm trying to make an async call to a domain. The following code works well if i specify a valid address with json response, but when the address is not valid, i want to be able to catch any possible exceptions.
How can i catch the returned exception?
Here an extract from stacktrace:
Message: Invalid JSON String
...
http.AsyncHTTPBuilder - Exception thrown from response delegate:
groovyx.net.http.HTTPBuilder$RequestConfigDelegate#420db81e
Here the code:
def http = new AsyncHTTPBuilder( poolSize : 1,
contentType : ContentType.JSON )
def futureResult
futureResult = http.request( "http://www.notexistingdomainxyzwq.com/",
Method.GET,
ContentType.JSON ) {
response.success = { resp, json ->
log.info("SUCCESS")
}
response.failure = { resp, json ->
log.info("ERROR")
}
}
log.info("Call started");
try {
while (!futureResult.done) {
log.info('waiting...')
log.info("DONE: ${futureResult.done}")
Thread.sleep(1000)
}
} catch(ex) {
log.error("EXCE ${ex}")
}
log.info("Call completed")
If you call futureResult.get() to block and wait for the result, this will throw the exception which you can catch:
try {
def result = futureResult.get()
log.info( "Done: $result" )
} catch(ex) {
log.error("EXCE ${ex}")
}

HTTPBuilder, returning JSON in not the correct format

I have a service that I am built\using returning data in the below format.
def responseData = [
'results': results,
'status': results ? "OK" : "Nothing present"
]
render(responseData as JSON)
The output looks like this, I have verified the output according to Fiddler
{"results":[{"class":"com.companyName.srm.ods.territory.Apo","id":2,"apoId":"5T9B0"}],"status":"OK"}
This is a simple POST call with a body of parameters from a search.
Using HTTPBuilder I get a different result
http.request(groovyx.net.http.Method.POST, groovyx.net.http.ContentType.URLENC) {req ->
uri.path = restUrl
body = requestData
response.success = {resp, json ->
println resp.statusLine.statusCode
println resp.statusLine
def slurper = new JsonSlurper()
String s = json.toString()
println s
returnJson = slurper.parseText(s)
}
response."422" = {resp, json ->
println ${resp.statusLine}
}
response.failure = {resp ->
println ${resp.statusLine}
}
}
["results":[{"class":"com.companyName.srm.ods.territory.Apo","id":2,"apoId":"5T9B0"}],"status":"OK":null]
This turns into a Mapped pair where the key is the JSON and the value is null, which is confusing as to why the HTTPBuilder is doing that.
In order to parse to JSON, I have to the following additional coding
s = s.replace(':null]', '')
s = s.replace('[', '')
This seems overly complicated for this type of implementation.
I have turned debug and nothing interesting is coming from that.
Any ideas
I use builder 0.7.1 and get json response the next way:
http.request(Method.POST, ContentType.TEXT) {
uri.path = pathToService
headers.'User' = user
headers.Accept = 'application/json'
body = requestBody //here I post some json
response.success = { resp, reader ->
//println reader.text;
println "response status: ${resp.statusLine}"
return = reader.text
}
response.failure = { resp, reader ->
println "Request failed with status ${resp.status}"
reader.responseData.results.each {
println " ${it.titleNoFormatting} : ${it.visibleUrl}"
}
}
}

HTTPBuilder set request contenttype

I am using the following code to execute a HTTP POST towards an external system. The problem is that the external system always gets a 'null' content type when using the code below. Is there a way to set the contenttype when using HTTPBuilder.
I tried other tools that execute the same request but then the remote system gets a good contentType ('application/json').
def execute(String baseUrl, String path, Map requestHeaders=[:], Map query=[:], method = Method.POST) {
try {
def http = new HTTPBuilder(baseUrl)
def result = null
// perform a ${method} request, expecting TEXT response
http.request(method, ContentType.JSON) {
uri.path = path
uri.query = query
// add possible headers
requestHeaders.each { key, value ->
headers."${key}" = "${value}"
}
// response handler for a success response code
response.success = { resp, reader ->
result = reader.getText()
}
}
return result
} catch (groovyx.net.http.HttpResponseException ex) {
ex.printStackTrace()
return null
} catch (java.net.ConnectException ex) {
ex.printStackTrace()
return null
}
}
Adding a specific header to the request seems to solve my problem.
def execute(String baseUrl, String path, Map requestHeaders=[:], Map query=[:], method = Method.POST) {
try {
def http = new HTTPBuilder(baseUrl)
def result = null
// perform a ${method} request, expecting TEXT response
http.request(method, ContentType.JSON) {
uri.path = path
uri.query = query
headers.'Content-Type' = 'application/json'
// add possible headers
requestHeaders.each { key, value ->
headers."${key}" = "${value}"
}
// response handler for a success response code
response.success = { resp, reader ->
result = reader.getText()
}
}
return result
} catch (groovyx.net.http.HttpResponseException ex) {
ex.printStackTrace()
return null
} catch (java.net.ConnectException ex) {
ex.printStackTrace()
return null
}
}
Try setting the requestContentType in the body of your request block...
http.request(method, ContentType.JSON) {
uri.path = path
uri.query = query
requestContentType = groovyx.net.http.ContentType.URLENC
.......
}