Class HTTPBuilder
- Direct Known Subclasses:
AsyncHTTPBuilder, RESTClient
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 the uri property in the request closure or
use HTTPBuilder's assigned default URI.
Response Parsing
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.
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 invalid input: '<'invalid input: '<' 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 invalid input: '<'invalid input: '<' 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}"
}
}
}
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classEncloses all properties and method calls used within therequest(Object, Method, Object, Closure)'config' closure argument. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected AuthConfigprotected booleanprivate org.apache.http.client.HttpClientprotected ContentEncodingRegistryprotected Objectprotected Objectprotected URIBuilderprotected EncoderRegistryprotected final org.apache.commons.logging.Logprotected ParserRegistry -
Constructor Summary
ConstructorsConstructorDescriptionCreates a new instance with anulldefault 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
Modifier and TypeMethodDescriptionprotected org.apache.http.client.HttpClientcreateClient(org.apache.http.params.HttpParams params) Override this method in a subclass to customize creation of the HttpClient instance.protected voidThis is the defaultresponse.failurehandler.protected ObjectdefaultSuccessHandler(HttpResponseDecorator resp, Object parsedData) This is the defaultresponse.successhandler.protected ObjectdoRequest(HTTPBuilder.RequestConfigDelegate delegate) Allrequestmethods delegate to this method.protected ObjectCreate aHTTPBuilder.RequestConfigDelegatefrom the given arguments, execute the config closure, then pass the delegate todoRequest(RequestConfigDelegate), which actually executes the request.Convenience method to perform an HTTP GET.Convenience method to perform an HTTP GET.getAuth()Used to access theAuthConfighandler used to configure common authentication mechanism.org.apache.http.client.HttpClientReturn the underlying HTTPClient that is used to handle HTTP requests.Retrieve the map of registered request content-type encoders.Map<?, groovy.lang.Closure> Retrieve the map of response code handlers.Map<?, ?> Get the map of default headers that will be added to all requests.Retrieve the map of registered response content-type parsers.getUri()Get the default URI used for requests that do not explicitly take auriparam.voidIgnores certificate issues for SSL connections.booleanIndicates whether or not this client should automatically send anAcceptheader based on thecontentTypeproperty.protected ObjectparseResponse(org.apache.http.HttpResponse resp, Object contentType) Parse the response data based on the given content-type.Convenience method to perform an HTTP POST.Convenience method to perform an HTTP form POST.Make an HTTP request to the default URI, and parse using the default content-type.Make an HTTP request using the default URI, with the given method, content-type, and configuration.Make a request for the given HTTP method and content-type, with additional options configured in theconfigClosure.voidSet an alternativeAuthConfigimplementation to handle authorization.voidsetAutoAcceptHeader(boolean shouldSendAcceptHeader) Indicate whether or not this cliernt should send anAcceptheader automatically based on thecontentTypeproperty.voidsetClient(org.apache.http.client.HttpClient client) voidsetContentEncoding(Object... encodings) Set acceptable request and response content-encodings.voidSet a custom registry used to handle differentcontent-encodingtypes in responses.voidsetContentType(Object ct) Set the default content type that will be used to select the appropriate request encoder and response parser.voidSet a custom registry used to handle different requestcontent-types.voidsetHeaders(Map<?, ?> headers) Set the default headers to add to all requests made by this builder instance.voidSet a custom registry used to handle different responsecontent-typesvoidSet the default HTTP proxy to be used for all requests.voidSet the default URI used for requests that do not explicitly take auriparam.voidshutdown()Release any system resources held by this instance.
-
Field Details
-
client
private org.apache.http.client.HttpClient client -
defaultURI
-
auth
-
log
protected final org.apache.commons.logging.Log log -
defaultContentType
-
defaultRequestContentType
-
autoAcceptHeader
protected boolean autoAcceptHeader -
defaultResponseHandlers
-
contentEncodingHandler
-
defaultRequestHeaders
-
encoders
-
parsers
-
-
Constructor Details
-
HTTPBuilder
public HTTPBuilder()Creates a new instance with anulldefault URI. -
HTTPBuilder
Give a default URI to be used for all request methods that don't explicitly take a URI parameter.- Parameters:
defaultURI- either aURL,URIor object whosetoString()produces a valid URI string. SeeURIBuilder.convertToURI(Object).- Throws:
URISyntaxException- if the given argument does not represent a valid URI
-
HTTPBuilder
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,URIor object whosetoString()produces a valid URI string. SeeURIBuilder.convertToURI(Object).defaultContentType- content-type string. SeeContentTypefor common types.- Throws:
URISyntaxException- if the uri argument does not represent a valid URI
-
-
Method Details
-
get
public Object get(Map<String, ?> args) throws org.apache.http.client.ClientProtocolException, IOException, URISyntaxExceptionConvenience method to perform an HTTP GET. It will use the HTTPBuilder's
registered response handlersto handle success or failure status codes. By default, thesuccessresponse 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.successresponse 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 URIIOExceptionorg.apache.http.client.ClientProtocolException- See Also:
-
get
public Object get(Map<String, ?> args, groovy.lang.Closure responseClosure) throws org.apache.http.client.ClientProtocolException, IOException, URISyntaxExceptionConvenience 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 handlerthrows 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.ClientProtocolExceptionIOExceptionURISyntaxException- 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, IOExceptionConvenience method to perform an HTTP POST. It will use the HTTPBuilder's
registered response handlersto handle success or failure status codes. By default, thesuccessresponse 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.successresponse handler- Parameters:
args- seeHTTPBuilder.RequestConfigDelegate.setPropertiesFromMap(Map)- Returns:
- whatever was returned from the response closure.
- Throws:
IOExceptionURISyntaxException- if a uri argument is given which does not represent a valid URIorg.apache.http.client.ClientProtocolException- See Also:
-
post
public Object post(Map<String, ?> args, groovy.lang.Closure responseClosure) throws URISyntaxException, org.apache.http.client.ClientProtocolException, IOExceptionConvenience 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 handlerthrows anHttpResponseException.The request body (specified by a
bodynamed parameter) will be converted to a url-encoded form string unless a differentrequestContentTypenamed 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.ClientProtocolExceptionIOExceptionURISyntaxException- 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 methodconfigClosure- request configuration options- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolExceptionIOException- See Also:
-
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 methodcontentType- either aContentTypeor valid content-type string.configClosure- request configuration options- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolExceptionIOException- See Also:
-
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.RequestConfigDelegatefor options.- Parameters:
uri- either aURL,URIor object whosetoString()produces a valid URI string. SeeURIBuilder.convertToURI(Object).method-HTTP methodcontentType- either aContentTypeor valid content-type string.configClosure- closure from which to configure options likeuri.path,request parameters,headers,request bodyandresponse handlers.- Returns:
- whatever value was returned by the executed response handler.
- Throws:
org.apache.http.client.ClientProtocolExceptionIOExceptionURISyntaxException- 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.RequestConfigDelegatefrom the given arguments, execute the config closure, then pass the delegate todoRequest(RequestConfigDelegate), which actually executes the request.- Throws:
org.apache.http.client.ClientProtocolExceptionIOException
-
doRequest
protected Object doRequest(HTTPBuilder.RequestConfigDelegate delegate) throws org.apache.http.client.ClientProtocolException, IOException Allrequestmethods delegate to this method.- Throws:
org.apache.http.client.ClientProtocolExceptionIOException
-
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-typeheader 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
nullif no parser could be found for this content-type. The parser will also returnnullif 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
-
defaultSuccessHandler
protected Object defaultSuccessHandler(HttpResponseDecorator resp, Object parsedData) throws ResponseParseException This is the default
response.successhandler. 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
BINARYorTEXT, the parser will return streaming content -- anInputStreamorReader. 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
This is the defaultresponse.failurehandler. It will be executed if no status-code-specific handler is set (i.e.response.'404'= {..}). This default handler will throw aHttpResponseExceptionwhen 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
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:
-
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
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.RequestConfigDelegateto retrieve the proper encoder for building the request content body.- Returns:
- a map of 'encoder' closures, keyed by content-type string.
-
setContentType
Set the default content type that will be used to select the appropriate request encoder and response parser. TheContentTypeenum 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 bodyas this content-type. CallingHTTPBuilder.RequestConfigDelegate.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-typeheader that is sent in the response. - Sets the
Acceptheader to this content-type for all requests (seeContentType.getAcceptHeader()). Note that anyAcceptheader 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-typeresponse 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 acontentTypenamed parameter.- Parameters:
ct- either aContentTypeor string value (i.e."text/xml".)- See Also:
- It tells the builder to encode any
-
getContentType
- Returns:
- default content type used for request and response.
-
setAutoAcceptHeader
public void setAutoAcceptHeader(boolean shouldSendAcceptHeader) Indicate whether or not this cliernt should send anAcceptheader automatically based on thecontentTypeproperty.- Parameters:
shouldSendAcceptHeader-trueif the client should automatically insert anAcceptheader, otherwisefalse.
-
isAutoAcceptHeader
public boolean isAutoAcceptHeader()Indicates whether or not this client should automatically send anAcceptheader based on thecontentTypeproperty. Default istrue.- Returns:
trueif the client should automatically add anAcceptheader to the request; iffalse, no header is added.
-
setContentEncoding
Set acceptable request and response content-encodings.- Parameters:
encodings- each Object should be either aContentEncoding.Typevalue, or acontent-encodingstring that is known by theContentEncodingRegistry- See Also:
-
setUri
Set the default URI used for requests that do not explicitly take auriparam.- Parameters:
uri- either aURL,URIor object whosetoString()produces a valid URI string. SeeURIBuilder.convertToURI(Object).- Throws:
URISyntaxException- if the uri argument does not represent a valid URI
-
getUri
Get the default URI used for requests that do not explicitly take auriparam.- Returns:
- a
URIBuilderinstance. Note that the return type is Object simply so that it matches with its JavaBeansetUri(Object)counterpart.
-
setHeaders
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 invalid input: '&' values.
-
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
Used to access theAuthConfighandler used to configure common authentication mechanism. Example:builder.auth.basic( 'myUser', 'somePassword' )
- Returns:
-
setAuthConfig
Set an alternativeAuthConfigimplementation to handle authorization.- Parameters:
ac- instance to use.
-
setEncoderRegistry
Set a custom registry used to handle different requestcontent-types.- Parameters:
er-
-
setParserRegistry
Set a custom registry used to handle different responsecontent-types- Parameters:
pr-
-
setContentEncodingRegistry
Set a custom registry used to handle differentcontent-encodingtypes in responses.- Parameters:
cer-
-
setProxy
-
ignoreSSLIssues
public void ignoreSSLIssues() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreExceptionIgnores 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:
-