Class HTTPBuilder

  • Direct Known Subclasses:
    AsyncHTTPBuilder, RESTClient

    public class HTTPBuilder
    extends java.lang.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 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 << 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}"
           }
         }
       }
     
    • Constructor Summary

      Constructors 
      Constructor Description
      HTTPBuilder()
      Creates a new instance with a null default URI.
      HTTPBuilder​(java.lang.Object defaultURI)
      Give a default URI to be used for all request methods that don't explicitly take a URI parameter.
      HTTPBuilder​(java.lang.Object defaultURI, java.lang.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 java.util.Map<java.lang.Object,​groovy.lang.Closure> buildDefaultResponseHandlers()
      Creates default response handlers for success and failure status codes.
      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 default response.failure handler.
      protected java.lang.Object defaultSuccessHandler​(HttpResponseDecorator resp, java.lang.Object parsedData)
      This is the default response.success handler.
      protected java.lang.Object doRequest​(HTTPBuilder.RequestConfigDelegate delegate)
      All request methods delegate to this method.
      protected java.lang.Object doRequest​(java.net.URI uri, Method method, java.lang.Object contentType, groovy.lang.Closure configClosure)
      Create a HTTPBuilder.RequestConfigDelegate from the given arguments, execute the config closure, then pass the delegate to doRequest(RequestConfigDelegate), which actually executes the request.
      java.lang.Object get​(java.util.Map<java.lang.String,​?> args)
      Convenience method to perform an HTTP GET.
      java.lang.Object get​(java.util.Map<java.lang.String,​?> args, groovy.lang.Closure responseClosure)
      Convenience method to perform an HTTP GET.
      AuthConfig getAuth()
      Used to access the AuthConfig handler used to configure common authentication mechanism.
      org.apache.http.client.HttpClient getClient()
      Return the underlying HTTPClient that is used to handle HTTP requests.
      java.lang.Object getContentType()  
      EncoderRegistry getEncoder()
      Retrieve the map of registered request content-type encoders.
      java.util.Map<?,​groovy.lang.Closure> getHandler()
      Retrieve the map of response code handlers.
      java.util.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.
      java.lang.Object getUri()
      Get the default URI used for requests that do not explicitly take a uri param.
      void ignoreSSLIssues()
      Ignores certificate issues for SSL connections.
      boolean isAutoAcceptHeader()
      Indicates whether or not this client should automatically send an Accept header based on the contentType property.
      protected java.lang.Object parseResponse​(org.apache.http.HttpResponse resp, java.lang.Object contentType)
      Parse the response data based on the given content-type.
      java.lang.Object post​(java.util.Map<java.lang.String,​?> args)
      Convenience method to perform an HTTP POST.
      java.lang.Object post​(java.util.Map<java.lang.String,​?> args, groovy.lang.Closure responseClosure)
      Convenience method to perform an HTTP form POST.
      java.lang.Object request​(Method method, groovy.lang.Closure configClosure)
      Make an HTTP request to the default URI, and parse using the default content-type.
      java.lang.Object request​(Method method, java.lang.Object contentType, groovy.lang.Closure configClosure)
      Make an HTTP request using the default URI, with the given method, content-type, and configuration.
      java.lang.Object request​(java.lang.Object uri, Method method, java.lang.Object contentType, groovy.lang.Closure configClosure)
      Make a request for the given HTTP method and content-type, with additional options configured in the configClosure.
      void setAuthConfig​(AuthConfig ac)
      Set an alternative AuthConfig implementation to handle authorization.
      void setAutoAcceptHeader​(boolean shouldSendAcceptHeader)
      Indicate whether or not this cliernt should send an Accept header automatically based on the contentType property.
      void setClient​(org.apache.http.client.HttpClient client)  
      void setContentEncoding​(java.lang.Object... encodings)
      Set acceptable request and response content-encodings.
      void setContentEncodingRegistry​(ContentEncodingRegistry cer)
      Set a custom registry used to handle different content-encoding types in responses.
      void setContentType​(java.lang.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 request content-types.
      void setHeaders​(java.util.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 response content-types
      void setProxy​(java.lang.String host, int port, java.lang.String scheme)
      Set the default HTTP proxy to be used for all requests.
      void setUri​(java.lang.Object uri)
      Set the default URI used for requests that do not explicitly take a uri param.
      void shutdown()
      Release any system resources held by this instance.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • client

        private org.apache.http.client.HttpClient client
      • log

        protected final org.apache.commons.logging.Log log
      • defaultContentType

        protected java.lang.Object defaultContentType
      • defaultRequestContentType

        protected java.lang.Object defaultRequestContentType
      • autoAcceptHeader

        protected boolean autoAcceptHeader
      • defaultResponseHandlers

        protected final java.util.Map<java.lang.Object,​groovy.lang.Closure> defaultResponseHandlers
      • defaultRequestHeaders

        protected final java.util.Map<java.lang.Object,​java.lang.Object> defaultRequestHeaders
    • Constructor Detail

      • HTTPBuilder

        public HTTPBuilder()
        Creates a new instance with a null default URI.
      • HTTPBuilder

        public HTTPBuilder​(java.lang.Object defaultURI)
                    throws java.net.URISyntaxException
        Give a default URI to be used for all request methods that don't explicitly take a URI parameter.
        Parameters:
        defaultURI - either a URL, URI or object whose toString() produces a valid URI string. See URIBuilder.convertToURI(Object).
        Throws:
        java.net.URISyntaxException - if the given argument does not represent a valid URI
      • HTTPBuilder

        public HTTPBuilder​(java.lang.Object defaultURI,
                           java.lang.Object defaultContentType)
                    throws java.net.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 a URL, URI or object whose toString() produces a valid URI string. See URIBuilder.convertToURI(Object).
        defaultContentType - content-type string. See ContentType for common types.
        Throws:
        java.net.URISyntaxException - if the uri argument does not represent a valid URI
    • Method Detail

      • get

        public java.lang.Object get​(java.util.Map<java.lang.String,​?> args,
                                    groovy.lang.Closure responseClosure)
                             throws org.apache.http.client.ClientProtocolException,
                                    java.io.IOException,
                                    java.net.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 an HttpResponseException.

        Parameters:
        args - see HTTPBuilder.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
        java.io.IOException
        java.net.URISyntaxException - if a uri argument is given which does not represent a valid URI
      • post

        public java.lang.Object post​(java.util.Map<java.lang.String,​?> args,
                                     groovy.lang.Closure responseClosure)
                              throws java.net.URISyntaxException,
                                     org.apache.http.client.ClientProtocolException,
                                     java.io.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 an HttpResponseException.

        The request body (specified by a body named parameter) will be converted to a url-encoded form string unless a different requestContentType named parameter is passed to this method. (See EncoderRegistry.encodeForm(Map).)

        Parameters:
        args - see HTTPBuilder.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
        java.io.IOException
        java.net.URISyntaxException - if a uri argument is given which does not represent a valid URI
      • request

        public java.lang.Object request​(Method method,
                                        groovy.lang.Closure configClosure)
                                 throws org.apache.http.client.ClientProtocolException,
                                        java.io.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
        java.io.IOException
        See Also:
        request(Object, Method, Object, Closure)
      • request

        public java.lang.Object request​(Method method,
                                        java.lang.Object contentType,
                                        groovy.lang.Closure configClosure)
                                 throws org.apache.http.client.ClientProtocolException,
                                        java.io.IOException
        Make an HTTP request using the default URI, with the given method, content-type, and configuration.
        Parameters:
        method - HTTP method
        contentType - either a ContentType 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
        java.io.IOException
        See Also:
        request(Object, Method, Object, Closure)
      • request

        public java.lang.Object request​(java.lang.Object uri,
                                        Method method,
                                        java.lang.Object contentType,
                                        groovy.lang.Closure configClosure)
                                 throws org.apache.http.client.ClientProtocolException,
                                        java.io.IOException,
                                        java.net.URISyntaxException
        Make a request for the given HTTP method and content-type, with additional options configured in the configClosure. See HTTPBuilder.RequestConfigDelegate for options.
        Parameters:
        uri - either a URL, URI or object whose toString() produces a valid URI string. See URIBuilder.convertToURI(Object).
        method - HTTP method
        contentType - either a ContentType or valid content-type string.
        configClosure - closure from which to configure options like uri.path, request parameters, headers, request body and response handlers.
        Returns:
        whatever value was returned by the executed response handler.
        Throws:
        org.apache.http.client.ClientProtocolException
        java.io.IOException
        java.net.URISyntaxException - if the uri argument does not represent a valid URI
      • doRequest

        protected java.lang.Object doRequest​(java.net.URI uri,
                                             Method method,
                                             java.lang.Object contentType,
                                             groovy.lang.Closure configClosure)
                                      throws org.apache.http.client.ClientProtocolException,
                                             java.io.IOException
        Create a HTTPBuilder.RequestConfigDelegate from the given arguments, execute the config closure, then pass the delegate to doRequest(RequestConfigDelegate), which actually executes the request.
        Throws:
        org.apache.http.client.ClientProtocolException
        java.io.IOException
      • doRequest

        protected java.lang.Object doRequest​(HTTPBuilder.RequestConfigDelegate delegate)
                                      throws org.apache.http.client.ClientProtocolException,
                                             java.io.IOException
        All request methods delegate to this method.
        Throws:
        org.apache.http.client.ClientProtocolException
        java.io.IOException
      • parseResponse

        protected java.lang.Object parseResponse​(org.apache.http.HttpResponse resp,
                                                 java.lang.Object contentType)
                                          throws HttpResponseException
        Parse the response data based on the given content-type. If the given content-type is ContentType.ANY, the content-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 return null 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
      • defaultSuccessHandler

        protected java.lang.Object defaultSuccessHandler​(HttpResponseDecorator resp,
                                                         java.lang.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 a response.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 or TEXT, the parser will return streaming content -- an InputStream or Reader. 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 response
        parsedData - parsed data as resolved from this instance's ParserRegistry
        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 default response.failure handler. It will be executed if no status-code-specific handler is set (i.e. response.'404'= {..}). This default handler will throw a HttpResponseException when executed. In most cases you will want to define your own response.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 java.util.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 calling EncoderRegistry.buildDefaultEncoderMap(). This method is also used by HTTPBuilder.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​(java.lang.Object ct)
        Set the default content type that will be used to select the appropriate request encoder and response parser. The ContentType 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:
        1. It tells the builder to encode any request body as this content-type. Calling RequestConfigDelegate#setRequestContentType(String) can override this on a per-request basis.
        2. Tells the builder to parse any response as this content-type, regardless of any content-type header that is sent in the response.
        3. Sets the Accept header to this content-type for all requests (see ContentType.getAcceptHeader()). Note that any Accept header explicitly set either in setHeaders(Map) or HTTPBuilder.RequestConfigDelegate.setHeaders(Map) will override this value.

        Additionally, if the content-type is set to ContentType.ANY, HTTPBuilder will rely on the content-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 a contentType named parameter.

        Parameters:
        ct - either a ContentType or string value (i.e. "text/xml".)
        See Also:
        EncoderRegistry, ParserRegistry
      • getContentType

        public java.lang.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 an Accept header automatically based on the contentType property.
        Parameters:
        shouldSendAcceptHeader - true if the client should automatically insert an Accept header, otherwise false.
      • isAutoAcceptHeader

        public boolean isAutoAcceptHeader()
        Indicates whether or not this client should automatically send an Accept header based on the contentType property. Default is true.
        Returns:
        true if the client should automatically add an Accept header to the request; if false, no header is added.
      • setContentEncoding

        public void setContentEncoding​(java.lang.Object... encodings)
        Set acceptable request and response content-encodings.
        Parameters:
        encodings - each Object should be either a ContentEncoding.Type value, or a content-encoding string that is known by the ContentEncodingRegistry
        See Also:
        ContentEncodingRegistry
      • setUri

        public void setUri​(java.lang.Object uri)
                    throws java.net.URISyntaxException
        Set the default URI used for requests that do not explicitly take a uri param.
        Parameters:
        uri - either a URL, URI or object whose toString() produces a valid URI string. See URIBuilder.convertToURI(Object).
        Throws:
        java.net.URISyntaxException - if the uri argument does not represent a valid URI
      • getUri

        public java.lang.Object getUri()
        Get the default URI used for requests that do not explicitly take a uri param.
        Returns:
        a URIBuilder instance. Note that the return type is Object simply so that it matches with its JavaBean setUri(Object) counterpart.
      • setHeaders

        public void setHeaders​(java.util.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 java.util.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 the AuthConfig handler used to configure common authentication mechanism. Example:
        builder.auth.basic( 'myUser', 'somePassword' )
        Returns:
      • setAuthConfig

        public void setAuthConfig​(AuthConfig ac)
        Set an alternative AuthConfig implementation to handle authorization.
        Parameters:
        ac - instance to use.
      • setEncoderRegistry

        public void setEncoderRegistry​(EncoderRegistry er)
        Set a custom registry used to handle different request content-types.
        Parameters:
        er -
      • setParserRegistry

        public void setParserRegistry​(ParserRegistry pr)
        Set a custom registry used to handle different response content-types
        Parameters:
        pr -
      • setContentEncodingRegistry

        public void setContentEncodingRegistry​(ContentEncodingRegistry cer)
        Set a custom registry used to handle different content-encoding types in responses.
        Parameters:
        cer -
      • setProxy

        public void setProxy​(java.lang.String host,
                             int port,
                             java.lang.String scheme)
        Set the default HTTP proxy to be used for all requests.
        Parameters:
        host - host name or IP
        port - port, or -1 for the default port
        scheme - usually "http" or "https," or null for the default
        See Also:
        HttpHost(String, int, String)
      • ignoreSSLIssues

        public void ignoreSSLIssues()
                             throws java.security.KeyManagementException,
                                    java.security.UnrecoverableKeyException,
                                    java.security.NoSuchAlgorithmException,
                                    java.security.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.
        Throws:
        java.security.KeyStoreException
        java.security.NoSuchAlgorithmException
        java.security.UnrecoverableKeyException
        java.security.KeyManagementException
      • shutdown

        public void shutdown()
        Release any system resources held by this instance.
        See Also:
        ClientConnectionManager.shutdown()