diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java index c7b136c7c9..9e2e32eea1 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,24 +23,24 @@ import org.springframework.http.HttpRequest; import org.springframework.util.concurrent.ListenableFuture; /** - * Represents a client-side asynchronous HTTP request. Created via an implementation of - * the {@link AsyncClientHttpRequestFactory}. - *

A {@code AsyncHttpRequest} can be {@linkplain #executeAsync() executed}, getting a - * future {@link ClientHttpResponse} which can be read from. + * Represents a client-side asynchronous HTTP request. Created via an + * implementation of the {@link AsyncClientHttpRequestFactory}. + * + *

A {@code AsyncHttpRequest} can be {@linkplain #executeAsync() executed}, + * getting a future {@link ClientHttpResponse} which can be read from. * * @author Arjen Poutsma * @since 4.0 - * @see AsyncClientHttpRequestFactory#createAsyncRequest(java.net.URI, org.springframework.http.HttpMethod) + * @see AsyncClientHttpRequestFactory#createAsyncRequest */ public interface AsyncClientHttpRequest extends HttpRequest, HttpOutputMessage { /** - * Execute this request asynchronously, resulting in a future + * Execute this request asynchronously, resulting in a Future handle. * {@link ClientHttpResponse} that can be read. * @return the future response result of the execution * @throws java.io.IOException in case of I/O errors */ ListenableFuture executeAsync() throws IOException; - } diff --git a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java index 4e3eb662d1..b482e3d6a3 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/AsyncClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,8 +22,8 @@ import java.net.URI; import org.springframework.http.HttpMethod; /** - * Factory for {@link AsyncClientHttpRequest} objects. Requests are created by the - * {@link #createAsyncRequest(URI, HttpMethod)} method. + * Factory for {@link AsyncClientHttpRequest} objects. + * Requests are created by the {@link #createAsyncRequest(URI, HttpMethod)} method. * * @author Arjen Poutsma * @since 4.0 @@ -31,8 +31,8 @@ import org.springframework.http.HttpMethod; public interface AsyncClientHttpRequestFactory { /** - * Create a new asynchronous {@link AsyncClientHttpRequest} for the specified URI and - * HTTP method. + * Create a new asynchronous {@link AsyncClientHttpRequest} for the specified URI + * and HTTP method. *

The returned request can be written to, and then executed by calling * {@link AsyncClientHttpRequest#executeAsync()}. * @param uri the URI to create a request for @@ -40,7 +40,6 @@ public interface AsyncClientHttpRequestFactory { * @return the created request * @throws IOException in case of I/O errors */ - AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) - throws IOException; + AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException; } diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java index 0344c0bb72..0f7d277de2 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,9 +44,8 @@ import org.springframework.util.concurrent.ListenableFutureCallbackRegistry; * * @author Oleg Kalnichevski * @author Arjen Poutsma - * @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory#createRequest(java.net.URI, - * org.springframework.http.HttpMethod) - * @since 3.1 + * @since 4.0 + * @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory#createRequest */ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { @@ -56,13 +55,14 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC private final HttpContext httpContext; - public HttpComponentsAsyncClientHttpRequest(HttpAsyncClient httpClient, - HttpUriRequest httpRequest, HttpContext httpContext) { + + HttpComponentsAsyncClientHttpRequest(HttpAsyncClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) { this.httpClient = httpClient; this.httpRequest = httpRequest; this.httpContext = httpContext; } + @Override public HttpMethod getMethod() { return HttpMethod.valueOf(this.httpRequest.getMethod()); @@ -74,48 +74,46 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC } @Override - protected ListenableFuture executeInternal(HttpHeaders headers, - byte[] bufferedOutput) throws IOException { + protected ListenableFuture executeInternal(HttpHeaders headers, byte[] bufferedOutput) + throws IOException { + HttpComponentsClientHttpRequest.addHeaders(this.httpRequest, headers); if (this.httpRequest instanceof HttpEntityEnclosingRequest) { - HttpEntityEnclosingRequest entityEnclosingRequest = - (HttpEntityEnclosingRequest) this.httpRequest; + HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest; HttpEntity requestEntity = new NByteArrayEntity(bufferedOutput); entityEnclosingRequest.setEntity(requestEntity); } final HttpResponseFutureCallback callback = new HttpResponseFutureCallback(); - final Future futureResponse = this.httpClient.execute(this.httpRequest, this.httpContext, callback); return new ClientHttpResponseFuture(futureResponse, callback); } + private static class HttpResponseFutureCallback implements FutureCallback { private final ListenableFutureCallbackRegistry callbacks = new ListenableFutureCallbackRegistry(); - public void addCallback( - ListenableFutureCallback callback) { - callbacks.addCallback(callback); + public void addCallback(ListenableFutureCallback callback) { + this.callbacks.addCallback(callback); } @Override public void completed(HttpResponse result) { - callbacks.success(new HttpComponentsAsyncClientHttpResponse(result)); + this.callbacks.success(new HttpComponentsAsyncClientHttpResponse(result)); } @Override public void failed(Exception ex) { - callbacks.failure(ex); + this.callbacks.failure(ex); } @Override public void cancelled() { } - } @@ -124,8 +122,7 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC private final HttpResponseFutureCallback callback; - private ClientHttpResponseFuture(Future futureResponse, - HttpResponseFutureCallback callback) { + public ClientHttpResponseFuture(Future futureResponse, HttpResponseFutureCallback callback) { super(futureResponse); this.callback = callback; } @@ -136,8 +133,7 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC } @Override - public void addCallback( - ListenableFutureCallback callback) { + public void addCallback(ListenableFutureCallback callback) { this.callback.addCallback(callback); } } diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java index 9fef0a61e7..e59d214c92 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -113,8 +113,7 @@ public class HttpComponentsAsyncClientHttpRequestFactory } @Override - public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) - throws IOException { + public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException { HttpAsyncClient asyncClient = getHttpAsyncClient(); startAsyncClient(); HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java index efd6ba13c6..b2f2d52858 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import org.springframework.http.HttpHeaders; * * @author Oleg Kalnichevski * @author Arjen Poutsma - * @since 3.1 + * @since 4.0 * @see HttpComponentsAsyncClientHttpRequest#executeAsync() */ final class HttpComponentsAsyncClientHttpResponse extends AbstractClientHttpResponse { @@ -76,9 +76,8 @@ final class HttpComponentsAsyncClientHttpResponse extends AbstractClientHttpResp @Override public void close() { - // HTTP responses returned by async HTTP client - // are not bound to an active connection and - // do not have to deallocate any resources + // HTTP responses returned by async HTTP client are not bound to an + // active connection and do not have to deallocate any resources... } } diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java index 38351cf837..8c3a9f5123 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -52,7 +53,7 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR private final HttpContext httpContext; - public HttpComponentsClientHttpRequest(CloseableHttpClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) { + HttpComponentsClientHttpRequest(CloseableHttpClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) { this.httpClient = httpClient; this.httpRequest = httpRequest; this.httpContext = httpContext; @@ -80,14 +81,13 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR HttpEntity requestEntity = new ByteArrayEntity(bufferedOutput); entityEnclosingRequest.setEntity(requestEntity); } - CloseableHttpResponse httpResponse = - this.httpClient.execute(this.httpRequest, this.httpContext); + CloseableHttpResponse httpResponse = this.httpClient.execute(this.httpRequest, this.httpContext); return new HttpComponentsClientHttpResponse(httpResponse); } + /** - * Adds the given headers to the given HTTP request. - * + * Add the given headers to the given HTTP request. * @param httpRequest the request to add the headers to * @param headers the headers to add */ diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java index cf3f61946c..fe8bb3787e 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +48,8 @@ import org.springframework.util.Assert; *

Allows to use a pre-configured {@link HttpClient} instance - * potentially with authentication, HTTP connection pooling, etc. * + *

NOTE: Requires Apache HttpComponents 4.3 or higher, as of Spring 4.0. + * * @author Oleg Kalnichevski * @author Arjen Poutsma * @since 3.1 diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpResponse.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpResponse.java index f0c8ff1e57..7b6ca8b894 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse @Override public InputStream getBody() throws IOException { HttpEntity entity = this.httpResponse.getEntity(); - return entity != null ? entity.getContent() : null; + return (entity != null ? entity.getContent() : null); } @Override @@ -83,12 +83,13 @@ final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse try { // Attempt to keep connection alive by consuming its remaining content EntityUtils.consume(this.httpResponse.getEntity()); - } finally { - // Paranoia + } + finally { this.httpResponse.close(); } } - catch (IOException ignore) { + catch (IOException ex) { + // Ignore exception on close... } } diff --git a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java index 6be05620ba..ddd96ce264 100644 --- a/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/HttpComponentsStreamingClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,18 +36,16 @@ import org.springframework.http.MediaType; import org.springframework.http.StreamingHttpOutputMessage; /** - * {@link ClientHttpRequest} implementation that uses Apache HttpComponents HttpClient to - * execute requests. + * {@link ClientHttpRequest} implementation that uses Apache HttpComponents + * HttpClient to execute requests. * - *

Created via the - * {@link org.springframework.http.client.HttpComponentsClientHttpRequestFactory}. + *

Created via the {@link HttpComponentsClientHttpRequestFactory}. * * @author Arjen Poutsma - * @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory#createRequest(java.net.URI, org.springframework.http.HttpMethod) * @since 4.0 + * @see HttpComponentsClientHttpRequestFactory#createRequest(java.net.URI, org.springframework.http.HttpMethod) */ -final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpRequest - implements StreamingHttpOutputMessage { +final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpRequest implements StreamingHttpOutputMessage { private final CloseableHttpClient httpClient; @@ -57,13 +55,14 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR private Body body; - public HttpComponentsStreamingClientHttpRequest(CloseableHttpClient httpClient, - HttpUriRequest httpRequest, HttpContext httpContext) { + + HttpComponentsStreamingClientHttpRequest(CloseableHttpClient httpClient, HttpUriRequest httpRequest, HttpContext httpContext) { this.httpClient = httpClient; this.httpRequest = httpRequest; this.httpContext = httpContext; } + @Override public HttpMethod getMethod() { return HttpMethod.valueOf(this.httpRequest.getMethod()); @@ -82,8 +81,7 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR @Override protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException { - throw new UnsupportedOperationException( - "getBody not supported when bufferRequestBody is false"); + throw new UnsupportedOperationException("getBody not supported"); } @Override @@ -91,26 +89,23 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR HttpComponentsClientHttpRequest.addHeaders(this.httpRequest, headers); if (this.httpRequest instanceof HttpEntityEnclosingRequest && body != null) { - HttpEntityEnclosingRequest entityEnclosingRequest = - (HttpEntityEnclosingRequest) this.httpRequest; - + HttpEntityEnclosingRequest entityEnclosingRequest = (HttpEntityEnclosingRequest) this.httpRequest; HttpEntity requestEntity = new StreamingHttpEntity(getHeaders(), body); entityEnclosingRequest.setEntity(requestEntity); } - CloseableHttpResponse httpResponse = - this.httpClient.execute(this.httpRequest, this.httpContext); + + CloseableHttpResponse httpResponse = this.httpClient.execute(this.httpRequest, this.httpContext); return new HttpComponentsClientHttpResponse(httpResponse); } + private static class StreamingHttpEntity implements HttpEntity { private final HttpHeaders headers; private final StreamingHttpOutputMessage.Body body; - - private StreamingHttpEntity(HttpHeaders headers, - StreamingHttpOutputMessage.Body body) { + public StreamingHttpEntity(HttpHeaders headers, StreamingHttpOutputMessage.Body body) { this.headers = headers; this.body = body; } @@ -127,32 +122,30 @@ final class HttpComponentsStreamingClientHttpRequest extends AbstractClientHttpR @Override public long getContentLength() { - return headers.getContentLength(); + return this.headers.getContentLength(); } @Override public Header getContentType() { - MediaType contentType = headers.getContentType(); - return contentType != null ? - new BasicHeader("Content-Type", contentType.toString()) : null; + MediaType contentType = this.headers.getContentType(); + return (contentType != null ? new BasicHeader("Content-Type", contentType.toString()) : null); } @Override public Header getContentEncoding() { - String contentEncoding = headers.getFirst("Content-Encoding"); - return contentEncoding != null ? - new BasicHeader("Content-Encoding", contentEncoding) : null; + String contentEncoding = this.headers.getFirst("Content-Encoding"); + return (contentEncoding != null ? new BasicHeader("Content-Encoding", contentEncoding) : null); } @Override public InputStream getContent() throws IOException, IllegalStateException { - throw new IllegalStateException(); + throw new IllegalStateException("No content available"); } @Override public void writeTo(OutputStream outputStream) throws IOException { - body.writeTo(outputStream); + this.body.writeTo(outputStream); } @Override