By default, HTTPBuilder classes will automatically parse XML responses using an XmlSlurper.
You can try the following example in the Groovy console (Groovy 1.6+ is needed for the @Grab macro):
import groovyx.net.http.*
@Grab(group='org.codehaus.groovy.modules.http-builder',
module='http-builder', version='0.5.2' )
def http = new HTTPBuilder( 'http://twitter.com/statuses/' )
http.get( path: 'user_timeline.xml', query:[id:'httpbuilder'] ) { resp, xml ->
println resp.status
xml.status.each { // iterate over each XML 'status' element in the response:
println it.created_at.text()
println " " + it.text.text()
}
}
HTTPBuilder will automatically detect the content-type (assuming the sends the correct response header) and parse the response as XML. It is not necessary (but optional) to explicitly specify the contentType: ContentType.XML parameter.
HTML response data will also be parsed automatically, by using NekoHTML which corrects the XML stream before it is passed to the XmlSlurper. The resulting behavior is that you can parse HTML as if it was well-formed XML.
Keep in mind that particularly when parsing HTML documents, they often refer to external DTDs. The required behavior of all JAXP XML parsers is to retrieve and parse any referenced entities (e.g. DTD, schema, etc.) every time the document is processed (yes, even if validation is disabled.) This can become costly when the referenced entity document never changes.
To avoid the overhead of downloading and parsing externally referenced documents for every request, the HTTPBuilder's built-in XML and HTML parser uses an XML Catalog to store a local copy of frequently used DTD and entity definitions. You can add additional entity files to the default parser's catalog as well.
XML data is serialized using StreamingMarkupBuilder. You can define the body property as a closure like so:
http.request( POST, XML ) {
body = {
auth {
user 'Bob'
password 'pass'
}
}
}
The body is then transformed to an XML string by file:///Users/tnichols/dev/http-builder/target/site/apidocs/groovyx/net/http/EncoderRegistry.html#encodeXML(java.lang.Object) EncoderRegistry.encodeXML(). Alternatively, the XML body may be passed as a raw string as well.
Another common request is "What if I want to display the raw XML rather than parse it?"
In order to do that, you're going to send a contentType parameter, to force HTTPBuilder (or RESTClient) to use the TEXT parser. However, since setting the contentType also affects the Accept request header, we might need to override that as well.
For Example:
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
def twitter = new RESTClient( 'https://twitter.com/statuses/' )
// ... auth & setup configuration omitted here ...
def resp = twitter.get( path : 'friends_timeline.xml', contentType : TEXT,
headers : [Accept : 'application/xml'] )
println resp.data.text // print the XML
Furthermore, you can use HTTPBuilder's defaults to reduce the number of parameters passed to each request method like so:
def twitter = new RESTClient( 'https://twitter.com/statuses/' ) // set a default response content-type twitter.contentType = TEXT /* set default headers which will override what's automatically sent in the request by the default contentType param */ twitter.headers = [ Accept : 'application/xml', ] def resp = twitter.get( path : 'friends_timeline.xml' )