Class HTTPBuilder
- java.lang.Object
-
- groovyx.net.http.HTTPBuilder
-
- Direct Known Subclasses:
AsyncHTTPBuilder
,RESTClient
public class HTTPBuilder extends Object
Groovy DSL for easily making HTTP requests, and handling request and response data. This class adds a number of convenience mechanisms built on top of Apache HTTPClient for things like URL-encoded POSTs and REST requests that require building and parsing JSON or XML. Convenient access to a few common authentication methods is also available.
Conventions
HTTPBuilder has properties for default headers, URI, contentType, etc. All of these values are also assignable (and in many cases, in much finer detail) from the
HTTPBuilder.RequestConfigDelegate
as well. In any cases where the value is not set on the delegate (from within a request closure,) the builder's default value is used.For instance, any methods that do not take a
uri
parameter assume you will set theuri
property in the request closure or use HTTPBuilder's assigneddefault URI
.Response Parsing
By default, HTTPBuilder uses
ContentType.ANY
as the default content-type. This means the value of the request'sAccept
header is*/*
, and the response parser is determined based on the responsecontent-type
header.If any contentType is given (either in
setContentType(Object)
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.Examples:
Perform an 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--------------------' }
Long form for other HTTP methods, and response-code-specific handlers. This is roughly equivalent to the above example.def http = new HTTPBuilder('http://www.google.com/search?q=groovy') http.request( GET, TEXT ) { req -> // executed for all successful responses: response.success = { resp, reader -> println 'my response handler!' assert resp.statusLine.statusCode == 200 println resp.statusLine System.out << reader // print response stream } // executed only if the response status code is 401: response.'404' = { resp -> println 'not found!' } }
You can also set a default response handler 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.failure = { resp -> println "Unexpected failure: ${resp.statusLine}" }
And... Automatic response parsing for registered content types!http.request( 'http://ajax.googleapis.com', 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}" } } }
- Author:
- Tom Nichols
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected class
HTTPBuilder.RequestConfigDelegate
Encloses all properties and method calls used within therequest(Object, Method, Object, Closure)
'config' closure argument.
-
Field Summary
Fields Modifier and Type Field Description protected AuthConfig
auth
protected boolean
autoAcceptHeader
protected ContentEncodingRegistry
contentEncodingHandler
protected Object
defaultContentType
protected Object
defaultRequestContentType
protected Map<Object,Object>
defaultRequestHeaders
protected Map<Object,groovy.lang.Closure>
defaultResponseHandlers
protected URIBuilder
defaultURI
protected EncoderRegistry
encoders
protected org.apache.commons.logging.Log
log
protected ParserRegistry
parsers
-
Constructor Summary
Constructors Constructor Description HTTPBuilder()
Creates a new instance with anull
default URI.HTTPBuilder(Object defaultURI)
Give a default URI to be used for all request methods that don't explicitly take a URI parameter.HTTPBuilder(Object defaultURI, Object defaultContentType)
Give a default URI to be used for all request methods that don't explicitly take a URI parameter, and a default content-type to be used for request encoding and response parsing.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected Map<Object,groovy.lang.Closure>
buildDefaultResponseHandlers()
protected org.apache.http.client.HttpClient
createClient(org.apache.http.params.HttpParams params)
Override this method in a subclass to customize creation of the HttpClient instance.protected void
defaultFailureHandler(HttpResponseDecorator resp)
This is the defaultresponse.failure
handler.protected Object
defaultSuccessHandler(HttpResponseDecorator resp, Object parsedData)
This is the defaultresponse.success
handler.protected Object
doRequest(HTTPBuilder.RequestConfigDelegate delegate)
Allrequest
methods delegate to this method.protected Object
doRequest(URI uri, Method method, Object contentType, groovy.lang.Closure configClosure)
Create aHTTPBuilder.RequestConfigDelegate
from the given arguments, execute the config closure, then pass the delegate todoRequest(RequestConfigDelegate)
, which actually executes the request.Object
get(Map<String,?> args)
Convenience method to perform an HTTP GET.Object
get(Map<String,?> args, groovy.lang.Closure responseClosure)
Convenience method to perform an HTTP GET.AuthConfig
getAuth()
Used to access theAuthConfig
handler used to configure common authentication mechanism.org.apache.http.client.HttpClient
getClient()
Return the underlying HTTPClient that is used to handle HTTP requests.Object
getContentType()
EncoderRegistry
getEncoder()
Retrieve the map of registered request content-type encoders.Map<?,groovy.lang.Closure>
getHandler()
Retrieve the map of response code handlers.Map<?,?>
getHeaders()
Get the map of default headers that will be added to all requests.ParserRegistry
getParser()
Retrieve the map of registered response content-type parsers.Object
getUri()
Get the default URI used for requests that do not explicitly take auri
param.void
ignoreSSLIssues()
Ignores certificate issues for SSL connections.boolean
isAutoAcceptHeader()
Indicates whether or not this client should automatically send anAccept
header based on thecontentType
property.protected Object
parseResponse(org.apache.http.HttpResponse resp, Object contentType)
Parse the response data based on the given content-type.Object
post(Map<String,?> args)
Convenience method to perform an HTTP POST.Object
post(Map<String,?> args, groovy.lang.Closure responseClosure)
Convenience method to perform an HTTP form POST.Object
request(Method method, groovy.lang.Closure configClosure)
Make an HTTP request to the default URI, and parse using the default content-type.Object
request(Method method, Object contentType, groovy.lang.Closure configClosure)
Make an HTTP request using the default URI, with the given method, content-type, and configuration.Object
request(Object uri, Method method, Object contentType, groovy.lang.Closure configClosure)
Make a request for the given HTTP method and content-type, with additional options configured in theconfigClosure
.void
setAuthConfig(AuthConfig ac)
Set an alternativeAuthConfig
implementation to handle authorization.void
setAutoAcceptHeader(boolean shouldSendAcceptHeader)
Indicate whether or not this cliernt should send anAccept
header automatically based on thecontentType
property.void
setClient(org.apache.http.client.HttpClient client)
void
setContentEncoding(Object... encodings)
Set acceptable request and response content-encodings.void
setContentEncodingRegistry(ContentEncodingRegistry cer)
Set a custom registry used to handle differentcontent-encoding
types in responses.void
setContentType(Object ct)
Set the default content type that will be used to select the appropriate request encoder and response parser.void
setEncoderRegistry(EncoderRegistry er)
Set a custom registry used to handle different requestcontent-type
s.void
setHeaders(Map<?,?> headers)
Set the default headers to add to all requests made by this builder instance.void
setParserRegistry(ParserRegistry pr)
Set a custom registry used to handle different responsecontent-type
svoid
setProxy(String host, int port, String scheme)
Set the default HTTP proxy to be used for all requests.void
setUri(Object uri)
Set the default URI used for requests that do not explicitly take auri
param.void
shutdown()
Release any system resources held by this instance.
-
-
-
Field Detail
-
defaultURI
protected URIBuilder defaultURI
-
auth
protected AuthConfig auth
-
log
protected final org.apache.commons.logging.Log log
-
defaultContentType
protected Object defaultContentType
-
defaultRequestContentType
protected Object defaultRequestContentType
-
autoAcceptHeader
protected boolean autoAcceptHeader
-
contentEncodingHandler
protected ContentEncodingRegistry contentEncodingHandler
-
encoders
protected EncoderRegistry encoders
-
parsers
protected ParserRegistry parsers
-
-
Constructor Detail
-
HTTPBuilder
public HTTPBuilder()
Creates a new instance with anull
default URI.
-
HTTPBuilder
public HTTPBuilder(Object defaultURI) throws URISyntaxException
Give a default URI to be used for all request methods that don't explicitly take a URI parameter.- Parameters:
defaultURI
- either aURL
,URI
or object whosetoString()
produces a valid URI string. SeeURIBuilder.convertToURI(Object)
.- Throws:
URISyntaxException
- if the given argument does not represent a valid URI
-
HTTPBuilder
public HTTPBuilder(Object defaultURI, Object defaultContentType) throws URISyntaxException
Give a default URI to be used for all request methods that don't explicitly take a URI parameter, and a default content-type to be used for request encoding and response parsing.- Parameters:
defaultURI
- either aURL
,URI
or object whosetoString()
produces a valid URI string. SeeURIBuilder.convertToURI(Object)
.defaultContentType
- content-type string. SeeContentType
for common types.- Throws:
URISyntaxException
- if the uri argument does not represent a valid URI
-
-
Method Detail
-
get
public Object get(Map<String,?> args) throws org.apache.http.client.ClientProtocolException, IOException, URISyntaxException
Convenience method to perform an HTTP GET. It will use the HTTPBuilder's
registered response handlers
to handle success or failure status codes. By default, thesuccess
response handler will attempt to parse the data and simply return the parsed object.Note: If using the
default
, be sure to read the caveat regarding streaming response data.success
response handler- Parameters:
args
- seeHTTPBuilder.RequestConfigDelegate.setPropertiesFromMap(Map)
- Returns:
- whatever was returned from the response closure.
- Throws:
URISyntaxException
- if a uri argument is given which does not represent a valid URIIOException
org.apache.http.client.ClientProtocolException
- See Also:
getHandler()
,defaultSuccessHandler(HttpResponseDecorator, Object)
,defaultFailureHandler(HttpResponseDecorator)
-
get
public Object get(Map<String,?> args, groovy.lang.Closure responseClosure) throws org.apache.http.client.ClientProtocolException, IOException, URISyntaxException
Convenience method to perform an HTTP GET. The response closure will be called only on a successful response.
A 'failed' response (i.e. any HTTP status code > 399) will be handled by the registered 'failure' handler. The
default failure handler
throws anHttpResponseException
.- Parameters:
args
- seeHTTPBuilder.RequestConfigDelegate.setPropertiesFromMap(Map)
responseClosure
- code to handle a successful HTTP response- Returns:
- any value returned by the response closure.
- Throws:
org.apache.http.client.ClientProtocolException
IOException
URISyntaxException
- if a uri argument is given which does not represent a valid URI
-
post
public Object post(Map<String,?> args) throws org.apache.http.client.ClientProtocolException, URISyntaxException, IOException
Convenience method to perform an HTTP POST. It will use the HTTPBuilder's
registered response handlers
to handle success or failure status codes. By default, thesuccess
response handler will attempt to parse the data and simply return the parsed object.Note: If using the
default
, be sure to read the caveat regarding streaming response data.success
response handler- Parameters:
args
- seeHTTPBuilder.RequestConfigDelegate.setPropertiesFromMap(Map)
- Returns:
- whatever was returned from the response closure.
- Throws:
IOException
URISyntaxException
- if a uri argument is given which does not represent a valid URIorg.apache.http.client.ClientProtocolException
- See Also:
getHandler()
,defaultSuccessHandler(HttpResponseDecorator, Object)
,defaultFailureHandler(HttpResponseDecorator)
-
post
public Object post(Map<String,?> args, groovy.lang.Closure responseClosure) throws URISyntaxException, org.apache.http.client.ClientProtocolException, IOException
Convenience method to perform an HTTP form POST. The response closure will be called only on a successful response.
A 'failed' response (i.e. any HTTP status code > 399) will be handled by the registered 'failure' handler. The
default failure handler
throws anHttpResponseException
.The request body (specified by a
body
named parameter) will be converted to a url-encoded form string unless a differentrequestContentType
named parameter is passed to this method. (SeeEncoderRegistry.encodeForm(Map)
.)- Parameters:
args
- seeHTTPBuilder.RequestConfigDelegate.setPropertiesFromMap(Map)
responseClosure
- code to handle a successful HTTP response- Returns:
- any value returned by the response closure.
- Throws:
org.apache.http.client.ClientProtocolException
IOException
URISyntaxException
- if a uri argument is given which does not represent a valid URI
-
request
public Object request(Method method, groovy.lang.Closure configClosure) throws org.apache.http.client.ClientProtocolException, IOException
Make an HTTP request to the default URI, and parse using the default content-type.- Parameters:
method
-HTTP method
configClosure
- request configuration options- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolException
IOException
- See Also:
request(Object, Method, Object, Closure)
-
request
public Object request(Method method, Object contentType, groovy.lang.Closure configClosure) throws org.apache.http.client.ClientProtocolException, IOException
Make an HTTP request using the default URI, with the given method, content-type, and configuration.- Parameters:
method
-HTTP method
contentType
- either aContentType
or valid content-type string.configClosure
- request configuration options- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolException
IOException
- See Also:
request(Object, Method, Object, Closure)
-
request
public Object request(Object uri, Method method, Object contentType, groovy.lang.Closure configClosure) throws org.apache.http.client.ClientProtocolException, IOException, URISyntaxException
Make a request for the given HTTP method and content-type, with additional options configured in theconfigClosure
. SeeHTTPBuilder.RequestConfigDelegate
for options.- Parameters:
uri
- either aURL
,URI
or object whosetoString()
produces a valid URI string. SeeURIBuilder.convertToURI(Object)
.method
-HTTP method
contentType
- either aContentType
or valid content-type string.configClosure
- closure from which to configure options likeuri.path
,request parameters
,headers
,request body
andresponse handlers
.- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolException
IOException
URISyntaxException
- if the uri argument does not represent a valid URI
-
doRequest
protected Object doRequest(URI uri, Method method, Object contentType, groovy.lang.Closure configClosure) throws org.apache.http.client.ClientProtocolException, IOException
Create aHTTPBuilder.RequestConfigDelegate
from the given arguments, execute the config closure, then pass the delegate todoRequest(RequestConfigDelegate)
, which actually executes the request.- Throws:
org.apache.http.client.ClientProtocolException
IOException
-
doRequest
protected Object doRequest(HTTPBuilder.RequestConfigDelegate delegate) throws org.apache.http.client.ClientProtocolException, IOException
Allrequest
methods delegate to this method.- Throws:
org.apache.http.client.ClientProtocolException
IOException
-
parseResponse
protected Object parseResponse(org.apache.http.HttpResponse resp, Object contentType) throws HttpResponseException
Parse the response data based on the given content-type. If the given content-type isContentType.ANY
, thecontent-type
header from the response will be used to determine how to parse the response.- Parameters:
resp
-contentType
-- Returns:
- whatever was returned from the parser retrieved for the given
content-type, or
null
if no parser could be found for this content-type. The parser will also returnnull
if the response does not contain any content (e.g. in response to a HEAD request). - Throws:
HttpResponseException
- if there is a error parsing the response
-
buildDefaultResponseHandlers
protected Map<Object,groovy.lang.Closure> buildDefaultResponseHandlers()
Creates default response handlers forsuccess
andfailure
status codes. This is used to populate the handler map when a new HTTPBuilder instance is created.- Returns:
- the default response handler map.
- See Also:
defaultSuccessHandler(HttpResponseDecorator, Object)
,defaultFailureHandler(HttpResponseDecorator)
-
defaultSuccessHandler
protected Object defaultSuccessHandler(HttpResponseDecorator resp, Object parsedData) throws ResponseParseException
This is the default
response.success
handler. It will be executed if the response is not handled by a status-code-specific handler (i.e.response.'200'= {..}
) and no generic 'success' handler is given (i.e.response.success = {..}
.) This handler simply returns the parsed data from the response body. In most cases you will probably want to define aresponse.success = {...}
handler from the request closure, which will replace the response handler defined by this method.Note for parsers that return streaming content:
For responses parsed as
BINARY
orTEXT
, the parser will return streaming content -- anInputStream
orReader
. In these cases, this handler will buffer the the response content before the network connection is closed.In practice, a user-supplied response handler closure is designed to handle streaming content so it can be read directly from the response stream without buffering, which will be much more efficient. Therefore, it is recommended that request method variants be used which explicitly accept a response handler closure in these cases.
- Parameters:
resp
- HTTP responseparsedData
- parsed data as resolved from this instance'sParserRegistry
- Returns:
- the parsed data object (whatever the parser returns).
- Throws:
ResponseParseException
- if there is an error buffering a streaming response.
-
defaultFailureHandler
protected void defaultFailureHandler(HttpResponseDecorator resp) throws HttpResponseException
This is the defaultresponse.failure
handler. It will be executed if no status-code-specific handler is set (i.e.response.'404'= {..}
). This default handler will throw aHttpResponseException
when executed. In most cases you will want to define your ownresponse.failure = {...}
handler from the request closure, if you don't want an exception to be thrown for 4xx and 5xx status responses.- Parameters:
resp
-- Throws:
HttpResponseException
-
getHandler
public Map<?,groovy.lang.Closure> getHandler()
Retrieve the map of response code handlers. Each map key is a response code as a string (i.e. '401') or either 'success' or 'failure'. Use this to set default response handlers, e.g.builder.handler.'401' = { resp -> println "${resp.statusLine}" }
- Returns:
- See Also:
Status
-
getParser
public ParserRegistry getParser()
Retrieve the map of registered response content-type parsers. Use this to set default response parsers, e.g.builder.parser.'text/javascript' = { resp -> return resp.entity.content // just returns an InputStream }
- Returns:
-
getEncoder
public EncoderRegistry getEncoder()
Retrieve the map of registered request content-type encoders. Use this to customize a request encoder for specific content-types, e.g.builder.encoder.'text/javascript' = { body -> def json = body.call( new JsonGroovyBuilder() ) return new StringEntity( json.toString() ) }
By default this map is populated by callingEncoderRegistry.buildDefaultEncoderMap()
. This method is also used byHTTPBuilder.RequestConfigDelegate
to retrieve the proper encoder for building the request content body.- Returns:
- a map of 'encoder' closures, keyed by content-type string.
-
setContentType
public void setContentType(Object ct)
Set the default content type that will be used to select the appropriate request encoder and response parser. TheContentType
enum holds some common content-types that may be used, i.e.import static ContentType.* builder.contentType = XML
Setting the default content-type does three things:- It tells the builder to encode any
request body
as this content-type. CallingRequestConfigDelegate#setRequestContentType(String)
can override this on a per-request basis. - Tells the builder to parse any response as this content-type,
regardless of any
content-type
header that is sent in the response. - Sets the
Accept
header to this content-type for all requests (seeContentType.getAcceptHeader()
). Note that anyAccept
header explicitly set either insetHeaders(Map)
orHTTPBuilder.RequestConfigDelegate.setHeaders(Map)
will override this value.
Additionally, if the content-type is set to
ContentType.ANY
, HTTPBuilder will rely on thecontent-type
response header to determine how to parse the response data. This allows the user to rely on response headers if they are accurate, or ignore them and forcibly use a certain response parser if so desired.This value is a default and may always be overridden on a per-request basis by using the
builder.request( Method, ContentType, Closure )
method or passing acontentType
named parameter.- Parameters:
ct
- either aContentType
or string value (i.e."text/xml"
.)- See Also:
EncoderRegistry
,ParserRegistry
- It tells the builder to encode any
-
getContentType
public Object getContentType()
- Returns:
- default content type used for request and response.
-
setAutoAcceptHeader
public void setAutoAcceptHeader(boolean shouldSendAcceptHeader)
Indicate whether or not this cliernt should send anAccept
header automatically based on thecontentType
property.- Parameters:
shouldSendAcceptHeader
-true
if the client should automatically insert anAccept
header, otherwisefalse
.
-
isAutoAcceptHeader
public boolean isAutoAcceptHeader()
Indicates whether or not this client should automatically send anAccept
header based on thecontentType
property. Default istrue
.- Returns:
true
if the client should automatically add anAccept
header to the request; iffalse
, no header is added.
-
setContentEncoding
public void setContentEncoding(Object... encodings)
Set acceptable request and response content-encodings.- Parameters:
encodings
- each Object should be either aContentEncoding.Type
value, or acontent-encoding
string that is known by theContentEncodingRegistry
- See Also:
ContentEncodingRegistry
-
setUri
public void setUri(Object uri) throws URISyntaxException
Set the default URI used for requests that do not explicitly take auri
param.- Parameters:
uri
- either aURL
,URI
or object whosetoString()
produces a valid URI string. SeeURIBuilder.convertToURI(Object)
.- Throws:
URISyntaxException
- if the uri argument does not represent a valid URI
-
getUri
public Object getUri()
Get the default URI used for requests that do not explicitly take auri
param.- Returns:
- a
URIBuilder
instance. Note that the return type is Object simply so that it matches with its JavaBeansetUri(Object)
counterpart.
-
setHeaders
public void setHeaders(Map<?,?> headers)
Set the default headers to add to all requests made by this builder instance. These values will replace any previously set default headers.- Parameters:
headers
- map of header names & values.
-
getHeaders
public Map<?,?> getHeaders()
Get the map of default headers that will be added to all requests. This is a 'live' collection so it may be used to add or remove default values.- Returns:
- the map of default header names and values.
-
getClient
public org.apache.http.client.HttpClient getClient()
Return the underlying HTTPClient that is used to handle HTTP requests.- Returns:
- the client instance.
-
setClient
public void setClient(org.apache.http.client.HttpClient client)
-
createClient
protected org.apache.http.client.HttpClient createClient(org.apache.http.params.HttpParams params)
Override this method in a subclass to customize creation of the HttpClient instance.- Parameters:
params
-- Returns:
-
getAuth
public AuthConfig getAuth()
Used to access theAuthConfig
handler used to configure common authentication mechanism. Example:builder.auth.basic( 'myUser', 'somePassword' )
- Returns:
-
setAuthConfig
public void setAuthConfig(AuthConfig ac)
Set an alternativeAuthConfig
implementation to handle authorization.- Parameters:
ac
- instance to use.
-
setEncoderRegistry
public void setEncoderRegistry(EncoderRegistry er)
Set a custom registry used to handle different requestcontent-type
s.- Parameters:
er
-
-
setParserRegistry
public void setParserRegistry(ParserRegistry pr)
Set a custom registry used to handle different responsecontent-type
s- Parameters:
pr
-
-
setContentEncodingRegistry
public void setContentEncodingRegistry(ContentEncodingRegistry cer)
Set a custom registry used to handle differentcontent-encoding
types in responses.- Parameters:
cer
-
-
setProxy
public void setProxy(String host, int port, String scheme)
Set the default HTTP proxy to be used for all requests.- Parameters:
host
- host name or IPport
- port, or -1 for the default portscheme
- usually "http" or "https," ornull
for the default- See Also:
HttpHost(String, int, String)
-
ignoreSSLIssues
public void ignoreSSLIssues() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException
Ignores certificate issues for SSL connections. Cert does not have to be from a trusted authority and the hostname does not need to be verified. This is primarily for dev situations that make use of localhost, build, and test servers.
-
shutdown
public void shutdown()
Release any system resources held by this instance.- See Also:
ClientConnectionManager.shutdown()
-
-