-
Notifications
You must be signed in to change notification settings - Fork 155
Home
See also newer fork at https://github.com/NCAR/httpbuilder --and a refactor at https://github.com/http-builder-ng/http-builder-ng
HTTPBuilder is optimized for three tasks:
- Streaming response handling,
- Automatic response parsing based on content-type
- Success & failure handling based on the response status code
To achieve this, HTTPBuilder exposes convenience methods for common request types, (i.e. GET and POST) and a more complex request method that allows fine-grained configuration of each request and response.
The following example shows most of the request method's features.
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.TEXT
// initialize a new builder and give a default URL
def http = new HTTPBuilder( 'http://www.google.com/search' )
http.request(GET,TEXT) { req ->
uri.path = '/mail/help/tasks/' // overrides any path in the default URL
headers.'User-Agent' = 'Mozilla/5.0'
response.success = { resp, reader ->
assert resp.status == 200
println "My response handler got response: ${resp.statusLine}"
println "Response length: ${resp.headers.'Content-Length'}"
System.out << reader // print response reader
}
// called only for a 404 (not found) status code:
response.'404' = { resp ->
println 'Not found'
}
}
If you are familiar with the HTTP protocol, most of the above should be self-explanatory. The request() method accepts three parameters: a method, content-type, and a request configuration closure. Within the configuration closure, we can fine-tune the parameters for this request, including manipulating portions of the URL, and adding request headers. A full list of properties that can be manipulated during request configuration can be found in the RequestConfigDelegate class.
The req parameter passed to the closure is an HttpRequest instance, which can be used to configure additional aspects of the request for which HTTPBuilder does not provide a wrapper.
The remaining 'response' definitions in the above example configure how the response is handled based on the HTTP status code returned by the server. In general, a "success" and "failure" response handler may be defined, or a response handler may be defined for a specific response code.
In the simplest case, no 'failure' handler needs to be defined; the default failure handler will throw an exception, which is triggered for any response code > 399. You can also customize default response handlers that will be in effect for all requests made by the 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}"
}
HTTPBuilder is also able to intelligently handle different response content-types. In this example, the response data is automatically parsed into a JSON object, which is then passed to the 'success' response handler.
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
def http = new HTTPBuilder( 'http://ajax.googleapis.com' )
http.request( GET, JSON ) {
uri.path = '/ajax/services/search/web'
uri.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}"
}
}
}
You can try the above example by adding the @Grab
macro (as demonstrated on the download page) with Groovy 1.6.
By default, new HTTPBuilder instances use ContentType.ANY
as the initial content-type. This means every request has an Accept: */*
header, and it is up to the server to decide what appropriate content-type to return. HTTPBuilder then chooses the appropriate parser from its ParserRegistry
based on the response Content-Type
header value.
If a contentType
is set (either in HTTPBuilder.setContentType(...)
or as a request method parameter), HTTPBuilder will attempt to parse the response using that content-type, regardless of what the server actually responds with. The first example on this page actually uses that strategy to parse an HTML document as plain text (i.e. by creating a Reader) rather than detecting an HTML content-type and using the default HTML parsing method. You can read more about automatic content-type parsing on the Content Types page.
Probably the quickest way to debug is to turn on logging for HTTPBuilder and Apache HttpClient. An example log4j configuration can be used to output headers and request/response content, as well as additional information on what HTTPBuilder is doing with the request and response.
To see the raw request and response output, change the Apache HttpClient logging parameters to DEBUG like so:
<category name="org.apache.http.headers">
<priority value="DEBUG" />
</category>
<category name="org.apache.http.wire">
<priority value="DEBUG" />
</category>
Some examples on this wiki use the @Grab
notation to resolve the HTTBuilder jar dependencies. To resolve using Maven use the following snippet:
<dependency>
<groupId>org.codehaus.groovy.modules.http-builder</groupId>
<artifactId>http-builder</artifactId>
<version>0.7</version>
</dependency>