Perform a simple HTTP GET and print the response:
def http = new HTTPBuilder('http://www.google.com') http.get( path : '/search', contentType : TEXT, query : [q:'Groovy'] ) { resp, reader -> println "response status: ${resp.statusLine}" println 'Response data: -----' System.out << reader println '\n--------------------' }
Note that in this version, the closure is a response handler block that is only executed on a successful response. A failure response (i.e. status code of 400 or greater) is handled by the builder's default failure handler .
This is a longer request form may be used for other HTTP methods, and also allows for response-code-specific handlers:
import static groovyx.net.http.Method.GET import static groovyx.net.http.ContentType.TEXT http.request(GET,TEXT) { req -> url.host = 'www.google.com' // overrides default URL headers.'User-Agent' = 'Mozilla/5.0' response.success = { resp, reader -> println 'my response handler!' assert resp.statusLine.statusCode == 200 println resp.statusLine System.out << reader // print response stream } response.'404' = { resp -> // fired only for a 401 (access denied) status code println 'Not found' } }
As mentioned above, you can also set a default "failure" response handler which is called for any status code > 399 that is not matched to a specific handler. Setting the value outside a request closure means it will apply to all future requests with this HTTPBuilder instance:
http.handler.'401' = { resp -> println "Access denied" } // Used for all other failure codes not handled by a code-specific handler: http.handler.failure = { resp -> println "Unexpected failure: ${resp.statusLine}" }
In this example, a registered content-type parser recognizes the response content-type header, and automatically parses the response data into a JSON object before it is passed to the 'success' response handler closure.
import static groovyx.net.http.Method.GET import static groovyx.net.http.ContentType.JSON http.request( 'http://ajax.googleapis.com', GET, JSON ) { url.path = '/ajax/services/search/web' url.query = [ v:'1.0', q: 'Calvin and Hobbes' ] response.success = { resp, json -> assert json.size() == 3 println "Query response: " json.responseData.results.each { println " ${it.titleNoFormatting} : ${it.visibleUrl}" } } }
By default, HTTPBuilder uses ContentType.ANY as the default content-type. This means the value of the request's Accept header is */* , and the response parser is determined based on the response content-type header value.
If any contentType is given (either in HTTPBuilder.setContentType(...) or as a request method parameter), the builder will attempt to parse the response using that content-type, regardless of what the server actually responds with.
To add parsing for new content types, simply add a new entry to the builder's ParserRegistry . For example, to parse comma-separated-values using OpenCSV :
import au.com.bytecode.opencsv.CSVReader http.parser.'text/csv' = { resp -> return new CSVReader( new InputStreamReader( resp.entity.content, ParserRegistry.getCharset( resp ) ) ) }
A CSVReader instance will then be passed as the second argument to the response handler. See IANA for a list of registered content-type names.
Probably the quickest way to debug is to turn on logging for HTTPBuilder and HttpClient. An example log4j configuration can be used to output headers and request/response body content.