diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java index 0fbba880fba..3048b760093 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java @@ -28,7 +28,7 @@ import org.springframework.http.HttpHeaders; * @author Arjen Poutsma * @since 3.0.6 */ -public abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequest { +abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequest { private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(); diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java index 74545bab50a..bf73ff61ef1 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequest.java @@ -30,12 +30,13 @@ import org.springframework.util.Assert; */ public abstract class AbstractClientHttpRequest implements ClientHttpRequest { - private boolean executed = false; - private final HttpHeaders headers = new HttpHeaders(); + private boolean executed = false; + + public final HttpHeaders getHeaders() { - return executed ? HttpHeaders.readOnlyHttpHeaders(headers) : this.headers; + return (this.executed ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers); } public final OutputStream getBody() throws IOException { @@ -43,14 +44,6 @@ public abstract class AbstractClientHttpRequest implements ClientHttpRequest { return getBodyInternal(this.headers); } - /** - * Abstract template method that returns the body. - * - * @param headers the HTTP headers - * @return the body output stream - */ - protected abstract OutputStream getBodyInternal(HttpHeaders headers) throws IOException; - public final ClientHttpResponse execute() throws IOException { checkExecuted(); ClientHttpResponse result = executeInternal(this.headers); @@ -62,13 +55,19 @@ public abstract class AbstractClientHttpRequest implements ClientHttpRequest { Assert.state(!this.executed, "ClientHttpRequest already executed"); } + + /** + * Abstract template method that returns the body. + * @param headers the HTTP headers + * @return the body output stream + */ + protected abstract OutputStream getBodyInternal(HttpHeaders headers) throws IOException; + /** * Abstract template method that writes the given headers and content to the HTTP request. - * * @param headers the HTTP headers * @return the response object for the executed request */ protected abstract ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException; - } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequestFactoryWrapper.java b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequestFactoryWrapper.java index 80c689de45a..8c493d312dd 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequestFactoryWrapper.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/AbstractClientHttpRequestFactoryWrapper.java @@ -32,9 +32,9 @@ public abstract class AbstractClientHttpRequestFactoryWrapper implements ClientH private final ClientHttpRequestFactory requestFactory; + /** * Creates a {@code AbstractClientHttpRequestFactoryWrapper} wrapping the given request factory. - * * @param requestFactory the request factory to be wrapped */ protected AbstractClientHttpRequestFactoryWrapper(ClientHttpRequestFactory requestFactory) { @@ -42,29 +42,27 @@ public abstract class AbstractClientHttpRequestFactoryWrapper implements ClientH this.requestFactory = requestFactory; } + /** - * {@inheritDoc} - * - *

This implementation simply calls {@link #createRequest(URI, HttpMethod, ClientHttpRequestFactory)} with the - * wrapped request factory provided to the {@linkplain #AbstractClientHttpRequestFactoryWrapper(ClientHttpRequestFactory) - * constructor}. + * This implementation simply calls {@link #createRequest(URI, HttpMethod, ClientHttpRequestFactory)} + * with the wrapped request factory provided to the + * {@linkplain #AbstractClientHttpRequestFactoryWrapper(ClientHttpRequestFactory) constructor}. */ public final ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { return createRequest(uri, httpMethod, requestFactory); } /** - * Create a new {@link ClientHttpRequest} for the specified URI and HTTP method by using the passed on request factory. + * Create a new {@link ClientHttpRequest} for the specified URI and HTTP method by using the + * passed-on request factory. *

Called from {@link #createRequest(URI, HttpMethod)}. - * * @param uri the URI to create a request for * @param httpMethod the HTTP method to execute * @param requestFactory the wrapped request factory * @return the created request * @throws IOException in case of I/O errors */ - protected abstract ClientHttpRequest createRequest(URI uri, - HttpMethod httpMethod, - ClientHttpRequestFactory requestFactory) throws IOException; + protected abstract ClientHttpRequest createRequest( + URI uri, HttpMethod httpMethod, ClientHttpRequestFactory requestFactory) throws IOException; } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestFactory.java b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestFactory.java index c48c0b572fc..47517bf1dce 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestFactory.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestFactory.java @@ -40,7 +40,7 @@ public class BufferingClientHttpRequestFactory extends AbstractClientHttpRequest throws IOException { ClientHttpRequest request = requestFactory.createRequest(uri, httpMethod); if (shouldBuffer(uri, httpMethod)) { - return new BufferingClientHttpRequest(request); + return new BufferingClientHttpRequestWrapper(request); } else { return request; diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java similarity index 76% rename from org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequest.java rename to org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java index c5e4abf6b90..813f98cfad9 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java @@ -31,29 +31,32 @@ import org.springframework.util.FileCopyUtils; * @author Arjen Poutsma * @since 3.1 */ -class BufferingClientHttpRequest extends AbstractBufferingClientHttpRequest { +final class BufferingClientHttpRequestWrapper extends AbstractBufferingClientHttpRequest { private final ClientHttpRequest request; - BufferingClientHttpRequest(ClientHttpRequest request) { + + BufferingClientHttpRequestWrapper(ClientHttpRequest request) { Assert.notNull(request, "'request' must not be null"); this.request = request; } + public HttpMethod getMethod() { - return request.getMethod(); + return this.request.getMethod(); } public URI getURI() { - return request.getURI(); + return this.request.getURI(); } @Override protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException { - request.getHeaders().putAll(headers); - OutputStream body = request.getBody(); + this.request.getHeaders().putAll(headers); + OutputStream body = this.request.getBody(); FileCopyUtils.copy(bufferedOutput, body); - ClientHttpResponse response = request.execute(); - return new BufferingClientHttpResponse(response); + ClientHttpResponse response = this.request.execute(); + return new BufferingClientHttpResponseWrapper(response); } + } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponse.java b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponseWrapper.java similarity index 71% rename from org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponse.java rename to org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponseWrapper.java index 955b9707e07..da9f39a52d5 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponse.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/BufferingClientHttpResponseWrapper.java @@ -25,43 +25,45 @@ import org.springframework.http.HttpStatus; import org.springframework.util.FileCopyUtils; /** - * Simple implementation of {@link ClientHttpResponse} that reads the request's body into memory, thus allowing for - * multiple invocations of {@link #getBody()}. + * Simple implementation of {@link ClientHttpResponse} that reads the request's body into memory, + * thus allowing for multiple invocations of {@link #getBody()}. * * @author Arjen Poutsma * @since 3.1 */ -class BufferingClientHttpResponse implements ClientHttpResponse { +final class BufferingClientHttpResponseWrapper implements ClientHttpResponse { private final ClientHttpResponse response; private byte[] body; - BufferingClientHttpResponse(ClientHttpResponse response) { + + BufferingClientHttpResponseWrapper(ClientHttpResponse response) { this.response = response; } + public HttpStatus getStatusCode() throws IOException { - return response.getStatusCode(); + return this.response.getStatusCode(); } public String getStatusText() throws IOException { - return response.getStatusText(); + return this.response.getStatusText(); } public HttpHeaders getHeaders() { - return response.getHeaders(); + return this.response.getHeaders(); } public InputStream getBody() throws IOException { - if (body == null) { - body = FileCopyUtils.copyToByteArray(response.getBody()); + if (this.body == null) { + this.body = FileCopyUtils.copyToByteArray(this.response.getBody()); } - return new ByteArrayInputStream(body); + return new ByteArrayInputStream(this.body); } public void close() { - response.close(); + this.response.close(); } } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequestFactory.java b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequestFactory.java index 1c0499e4f02..448edf8f1c3 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequestFactory.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/CommonsClientHttpRequestFactory.java @@ -60,7 +60,7 @@ public class CommonsClientHttpRequestFactory implements ClientHttpRequestFactory * {@link HttpClient} that uses a default {@link MultiThreadedHttpConnectionManager}. */ public CommonsClientHttpRequestFactory() { - httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); + this.httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); this.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingSimpleClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java similarity index 94% rename from org.springframework.web/src/main/java/org/springframework/http/client/BufferingSimpleClientHttpRequest.java rename to org.springframework.web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java index d6f8ecc3755..989d9e4d281 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/BufferingSimpleClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java @@ -35,11 +35,12 @@ import org.springframework.util.FileCopyUtils; * @since 3.0 * @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod) */ -final class BufferingSimpleClientHttpRequest extends AbstractBufferingClientHttpRequest { +final class SimpleBufferingClientHttpRequest extends AbstractBufferingClientHttpRequest { private final HttpURLConnection connection; - BufferingSimpleClientHttpRequest(HttpURLConnection connection) { + + SimpleBufferingClientHttpRequest(HttpURLConnection connection) { this.connection = connection; } @@ -69,9 +70,7 @@ final class BufferingSimpleClientHttpRequest extends AbstractBufferingClientHttp if (this.connection.getDoOutput()) { this.connection.setFixedLengthStreamingMode(bufferedOutput.length); } - this.connection.connect(); - if (this.connection.getDoOutput()) { FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream()); } diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java index 8416d916109..718ad75dd66 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpRequestFactory.java @@ -30,22 +30,24 @@ import org.springframework.util.Assert; * {@link ClientHttpRequestFactory} implementation that uses standard J2SE facilities. * * @author Arjen Poutsma + * @since 3.0 * @see java.net.HttpURLConnection * @see CommonsClientHttpRequestFactory - * @since 3.0 */ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory { private static final int DEFAULT_CHUNK_SIZE = 4096; + private Proxy proxy; private boolean bufferRequestBody = true; private int chunkSize = DEFAULT_CHUNK_SIZE; + /** - * Sets the {@link Proxy} to use for this request factory. + * Set the {@link Proxy} to use for this request factory. */ public void setProxy(Proxy proxy) { this.proxy = proxy; @@ -54,12 +56,11 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory /** * Indicates whether this request factory should buffer the {@linkplain ClientHttpRequest#getBody() request body} * internally. - *

Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended to change this - * property to {@code false}, so as not to run out of memory. This will result in a {@link ClientHttpRequest} - * that either streams directly to the underlying {@link HttpURLConnection} (if the - * {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} is known in advance), or that will - * use "Chunked transfer encoding" (if the {@code Content-Length} is not known in advance). - * + *

Default is {@code true}. When sending large amounts of data via POST or PUT, it is recommended + * to change this property to {@code false}, so as not to run out of memory. This will result in a + * {@link ClientHttpRequest} that either streams directly to the underlying {@link HttpURLConnection} + * (if the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} is known in advance), + * or that will use "Chunked transfer encoding" (if the {@code Content-Length} is not known in advance). * @see #setChunkSize(int) * @see HttpURLConnection#setFixedLengthStreamingMode(int) */ @@ -72,43 +73,42 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory *

Note that this parameter is only used when {@link #setBufferRequestBody(boolean) bufferRequestBody} is set * to {@code false}, and the {@link org.springframework.http.HttpHeaders#getContentLength() Content-Length} * is not known in advance. - * * @see #setBufferRequestBody(boolean) */ public void setChunkSize(int chunkSize) { this.chunkSize = chunkSize; } + public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { - HttpURLConnection connection = openConnection(uri.toURL(), proxy); + HttpURLConnection connection = openConnection(uri.toURL(), this.proxy); prepareConnection(connection, httpMethod.name()); - if (bufferRequestBody) { - return new BufferingSimpleClientHttpRequest(connection); + if (this.bufferRequestBody) { + return new SimpleBufferingClientHttpRequest(connection); } else { - return new StreamingSimpleClientHttpRequest(connection, chunkSize); + return new SimpleStreamingClientHttpRequest(connection, this.chunkSize); } } /** - * Opens and returns a connection to the given URL.

The default implementation uses the given {@linkplain - * #setProxy(java.net.Proxy) proxy} - if any - to open a connection. - * + * Opens and returns a connection to the given URL. + *

The default implementation uses the given {@linkplain #setProxy(java.net.Proxy) proxy} - + * if any - to open a connection. * @param url the URL to open a connection to * @param proxy the proxy to use, may be {@code null} * @return the opened connection * @throws IOException in case of I/O errors */ protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException { - URLConnection urlConnection = proxy != null ? url.openConnection(proxy) : url.openConnection(); + URLConnection urlConnection = (proxy != null ? url.openConnection(proxy) : url.openConnection()); Assert.isInstanceOf(HttpURLConnection.class, urlConnection); return (HttpURLConnection) urlConnection; } /** - * Template method for preparing the given {@link HttpURLConnection}.

The default implementation prepares the - * connection for input and output, and sets the HTTP method. - * + * Template method for preparing the given {@link HttpURLConnection}. + *

The default implementation prepares the connection for input and output, and sets the HTTP method. * @param connection the connection to prepare * @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.) * @throws IOException in case of I/O errors @@ -130,4 +130,4 @@ public class SimpleClientHttpRequestFactory implements ClientHttpRequestFactory connection.setRequestMethod(httpMethod); } -} \ No newline at end of file +} diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java index 56f23a3d853..5a8e3f04b34 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleClientHttpResponse.java @@ -26,8 +26,8 @@ import org.springframework.util.StringUtils; /** * {@link ClientHttpResponse} implementation that uses standard J2SE facilities. - * Obtained via {@link BufferingSimpleClientHttpRequest#execute()} and - * {@link StreamingSimpleClientHttpRequest#execute()}. + * Obtained via {@link SimpleBufferingClientHttpRequest#execute()} and + * {@link SimpleStreamingClientHttpRequest#execute()}. * * @author Arjen Poutsma * @since 3.0 diff --git a/org.springframework.web/src/main/java/org/springframework/http/client/StreamingSimpleClientHttpRequest.java b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java similarity index 89% rename from org.springframework.web/src/main/java/org/springframework/http/client/StreamingSimpleClientHttpRequest.java rename to org.springframework.web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java index 2888fea4e70..7ef375a6c93 100644 --- a/org.springframework.web/src/main/java/org/springframework/http/client/StreamingSimpleClientHttpRequest.java +++ b/org.springframework.web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java @@ -36,7 +36,7 @@ import org.springframework.http.HttpMethod; * @since 3.0 * @see SimpleClientHttpRequestFactory#createRequest(java.net.URI, HttpMethod) */ -public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest { +final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest { private final HttpURLConnection connection; @@ -44,7 +44,8 @@ public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest private OutputStream body; - StreamingSimpleClientHttpRequest(HttpURLConnection connection, int chunkSize) { + + SimpleStreamingClientHttpRequest(HttpURLConnection connection, int chunkSize) { this.connection = connection; this.chunkSize = chunkSize; } @@ -64,13 +65,13 @@ public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest @Override protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - if (body == null) { + if (this.body == null) { int contentLength = (int) headers.getContentLength(); if (contentLength >= 0) { this.connection.setFixedLengthStreamingMode(contentLength); } else { - this.connection.setChunkedStreamingMode(chunkSize); + this.connection.setChunkedStreamingMode(this.chunkSize); } for (Map.Entry> entry : headers.entrySet()) { String headerName = entry.getKey(); @@ -81,14 +82,14 @@ public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest this.connection.connect(); this.body = this.connection.getOutputStream(); } - return new NonClosingOutputStream(body); + return new NonClosingOutputStream(this.body); } @Override protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { try { - if (body != null) { - body.close(); + if (this.body != null) { + this.body.close(); } } catch (IOException ex) { @@ -97,6 +98,7 @@ public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest return new SimpleClientHttpResponse(this.connection); } + private static class NonClosingOutputStream extends FilterOutputStream { private NonClosingOutputStream(OutputStream out) { @@ -108,5 +110,4 @@ public class StreamingSimpleClientHttpRequest extends AbstractClientHttpRequest } } - }