org.springframework.remoting.httpinvoker

## Class CommonsHttpInvokerRequestExecutor

- java.lang.Object
- - org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor
  - - org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor

- All Implemented Interfaces:
    Aware, BeanClassLoaderAware, HttpInvokerRequestExecutor

      public class CommonsHttpInvokerRequestExecutor
      extends AbstractHttpInvokerRequestExecutor

  `HttpInvokerRequestExecutor` implementation that uses Jakarta Commons HttpClient to execute POST requests. Requires Commons HttpClient 3.0 or higher.

  Allows to use a pre-configured `HttpClient` instance, potentially with authentication, HTTP connection pooling, etc. Also designed for easy subclassing, providing specific template methods.

  Since:
    1.1
  Author:
    Juergen Hoeller, Mark Fisher
  See Also:
    `SimpleHttpInvokerRequestExecutor`

- - ### Field Summary

    - ### Fields inherited from class org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor

      `CONTENT_TYPE_SERIALIZED_OBJECT, ENCODING_GZIP, HTTP_HEADER_ACCEPT_ENCODING, HTTP_HEADER_ACCEPT_LANGUAGE, HTTP_HEADER_CONTENT_ENCODING, HTTP_HEADER_CONTENT_LENGTH, HTTP_HEADER_CONTENT_TYPE, HTTP_METHOD_POST, logger`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `CommonsHttpInvokerRequestExecutor()` Create a new CommonsHttpInvokerRequestExecutor with a default HttpClient that uses a default MultiThreadedHttpConnectionManager.
    `CommonsHttpInvokerRequestExecutor(HttpClient httpClient)` Create a new CommonsHttpInvokerRequestExecutor with the given HttpClient instance.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected PostMethod` | `createPostMethod(HttpInvokerClientConfiguration config)` Create a PostMethod for the given configuration.
    `protected RemoteInvocationResult` | `doExecuteRequest(HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)` Execute the given request through Commons HttpClient.
    `protected void` | `executePostMethod(HttpInvokerClientConfiguration config, HttpClient httpClient, PostMethod postMethod)` Execute the given PostMethod instance.
    `HttpClient` | `getHttpClient()` Return the HttpClient instance that this request executor uses.
    `protected InputStream` | `getResponseBody(HttpInvokerClientConfiguration config, PostMethod postMethod)` Extract the response body from the given executed remote invocation request.
    `protected boolean` | `isGzipResponse(PostMethod postMethod)` Determine whether the given response indicates a GZIP response.
    `void` | `setConnectTimeout(int timeout)` Set the connection timeout for the underlying HttpClient.
    `void` | `setHttpClient(HttpClient httpClient)` Set the HttpClient instance to use for this request executor.
    `void` | `setReadTimeout(int timeout)` Set the socket read timeout for the underlying HttpClient.
    `protected void` | `setRequestBody(HttpInvokerClientConfiguration config, PostMethod postMethod, ByteArrayOutputStream baos)` Set the given serialized remote invocation as request body.
    `protected void` | `validateResponse(HttpInvokerClientConfiguration config, PostMethod postMethod)` Validate the given response as contained in the PostMethod object, throwing an exception if it does not correspond to a successful HTTP response.

    - ### Methods inherited from class org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor

      `createObjectInputStream, decorateInputStream, decorateOutputStream, doReadRemoteInvocationResult, doWriteRemoteInvocation, executeRequest, getBeanClassLoader, getByteArrayOutputStream, getContentType, isAcceptGzipEncoding, readRemoteInvocationResult, setAcceptGzipEncoding, setBeanClassLoader, setContentType, writeRemoteInvocation`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### CommonsHttpInvokerRequestExecutor

          public CommonsHttpInvokerRequestExecutor()

      Create a new CommonsHttpInvokerRequestExecutor with a default HttpClient that uses a default MultiThreadedHttpConnectionManager. Sets the socket read timeout to `DEFAULT_READ_TIMEOUT_MILLISECONDS`.
      See Also:
        `HttpClient`, `MultiThreadedHttpConnectionManager`

    - #### CommonsHttpInvokerRequestExecutor

          public CommonsHttpInvokerRequestExecutor(HttpClient httpClient)

      Create a new CommonsHttpInvokerRequestExecutor with the given HttpClient instance. The socket read timeout of the provided HttpClient will not be changed.
      Parameters:
        `httpClient` - the HttpClient instance to use for this request executor

  - ### Method Detail

    - #### setHttpClient

          public void setHttpClient(HttpClient httpClient)

      Set the HttpClient instance to use for this request executor.

    - #### getHttpClient

          public HttpClient getHttpClient()

      Return the HttpClient instance that this request executor uses.

    - #### setConnectTimeout

          public void setConnectTimeout(int timeout)

      Set the connection timeout for the underlying HttpClient. A timeout value of 0 specifies an infinite timeout.
      Parameters:
        `timeout` - the timeout value in milliseconds
      See Also:
        `HttpConnectionParams.setConnectionTimeout(int)`

    - #### setReadTimeout

          public void setReadTimeout(int timeout)

      Set the socket read timeout for the underlying HttpClient. A timeout value of 0 specifies an infinite timeout.
      Parameters:
        `timeout` - the timeout value in milliseconds
      See Also:
        `HttpConnectionParams.setSoTimeout(int)`, `DEFAULT_READ_TIMEOUT_MILLISECONDS`

    - #### doExecuteRequest

          protected RemoteInvocationResult doExecuteRequest(HttpInvokerClientConfiguration config,
                                                ByteArrayOutputStream baos)
                                                     throws IOException,
                                                            ClassNotFoundException

      Execute the given request through Commons HttpClient.

      This method implements the basic processing workflow: The actual work happens in this class's template methods.

      Specified by:
        `doExecuteRequest` in class `AbstractHttpInvokerRequestExecutor`
      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
        `baos` - the ByteArrayOutputStream that contains the serialized RemoteInvocation object
      Returns:
        the RemoteInvocationResult object
      Throws:
        `IOException` - if thrown by I/O operations
        `ClassNotFoundException` - if thrown during deserialization
      See Also:
        `createPostMethod(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration)`, `setRequestBody(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration, org.apache.commons.httpclient.methods.PostMethod, java.io.ByteArrayOutputStream)`, `executePostMethod(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration, org.apache.commons.httpclient.HttpClient, org.apache.commons.httpclient.methods.PostMethod)`, `validateResponse(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration, org.apache.commons.httpclient.methods.PostMethod)`, `getResponseBody(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration, org.apache.commons.httpclient.methods.PostMethod)`

    - #### createPostMethod

          protected PostMethod createPostMethod(HttpInvokerClientConfiguration config)
                                         throws IOException

      Create a PostMethod for the given configuration.

      The default implementation creates a standard PostMethod with "application/x-java-serialized-object" as "Content-Type" header.

      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
      Returns:
        the PostMethod instance
      Throws:
        `IOException` - if thrown by I/O methods

    - #### setRequestBody

          protected void setRequestBody(HttpInvokerClientConfiguration config,
                            PostMethod postMethod,
                            ByteArrayOutputStream baos)
                                 throws IOException

      Set the given serialized remote invocation as request body.

      The default implementation simply sets the serialized invocation as the PostMethod's request body. This can be overridden, for example, to write a specific encoding and to potentially set appropriate HTTP request headers.

      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
        `postMethod` - the PostMethod to set the request body on
        `baos` - the ByteArrayOutputStream that contains the serialized RemoteInvocation object
      Throws:
        `IOException` - if thrown by I/O methods
      See Also:
        `EntityEnclosingMethod.setRequestBody(java.io.InputStream)`, `EntityEnclosingMethod.setRequestEntity(org.apache.commons.httpclient.methods.RequestEntity)`, `InputStreamRequestEntity`

    - #### executePostMethod

          protected void executePostMethod(HttpInvokerClientConfiguration config,
                               HttpClient httpClient,
                               PostMethod postMethod)
                                    throws IOException

      Execute the given PostMethod instance.
      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
        `httpClient` - the HttpClient to execute on
        `postMethod` - the PostMethod to execute
      Throws:
        `IOException` - if thrown by I/O methods
      See Also:
        `HttpClient.executeMethod(org.apache.commons.httpclient.HttpMethod)`

    - #### validateResponse

          protected void validateResponse(HttpInvokerClientConfiguration config,
                              PostMethod postMethod)
                                   throws IOException

      Validate the given response as contained in the PostMethod object, throwing an exception if it does not correspond to a successful HTTP response.

      Default implementation rejects any HTTP status code beyond 2xx, to avoid parsing the response body and trying to deserialize from a corrupted stream.

      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
        `postMethod` - the executed PostMethod to validate
      Throws:
        `IOException` - if validation failed
      See Also:
        `HttpMethodBase.getStatusCode()`, `HttpException`

    - #### getResponseBody

          protected InputStream getResponseBody(HttpInvokerClientConfiguration config,
                                    PostMethod postMethod)
                                         throws IOException

      Extract the response body from the given executed remote invocation request.

      The default implementation simply fetches the PostMethod's response body stream. If the response is recognized as GZIP response, the InputStream will get wrapped in a GZIPInputStream.

      Parameters:
        `config` - the HTTP invoker configuration that specifies the target service
        `postMethod` - the PostMethod to read the response body from
      Returns:
        an InputStream for the response body
      Throws:
        `IOException` - if thrown by I/O methods
      See Also:
        `isGzipResponse(org.apache.commons.httpclient.methods.PostMethod)`, `GZIPInputStream`, `HttpMethodBase.getResponseBodyAsStream()`, `HttpMethodBase.getResponseHeader(String)`

    - #### isGzipResponse

          protected boolean isGzipResponse(PostMethod postMethod)

      Determine whether the given response indicates a GZIP response.

      The default implementation checks whether the HTTP "Content-Encoding" header contains "gzip" (in any casing).

      Parameters:
        `postMethod` - the PostMethod to check
      Returns:
        whether the given response indicates a GZIP response