org.springframework.remoting.httpinvoker
Class CommonsHttpInvokerRequestExecutor

java.lang.Object
  extended by org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor
      extended by 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
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
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 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.


setReadTimeout

public void setReadTimeout(int timeout)
Set the socket read timeout for the underlying HttpClient. A value of 0 means never 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 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.

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