diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java new file mode 100644 index 00000000000..0e3f836f2f3 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/client/OkHttpAsyncClientHttpRequest.java @@ -0,0 +1,104 @@ +/* + * Copyright 2002-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.client; + +import java.io.IOException; +import java.net.URI; + +import com.squareup.okhttp.Call; +import com.squareup.okhttp.Callback; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.SettableListenableFuture; + +/** + * {@link AsyncClientHttpRequest} implementation that uses OkHttp to execute requests. + * + *

Created via the {@link OkHttpClientHttpRequestFactory}. + * + * @author Luciano Leggieri + * @author Arjen Poutsma + * @since 4.3 + */ +class OkHttpAsyncClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest { + + private final OkHttpClient client; + + private final URI uri; + + private final HttpMethod method; + + + public OkHttpAsyncClientHttpRequest(OkHttpClient client, URI uri, HttpMethod method) { + this.client = client; + this.uri = uri; + this.method = method; + } + + + @Override + public HttpMethod getMethod() { + return this.method; + } + + @Override + public URI getURI() { + return this.uri; + } + + @Override + protected ListenableFuture executeInternal(HttpHeaders headers, byte[] content) + throws IOException { + + Request request = OkHttpClientHttpRequestFactory + .buildRequest(headers, content, this.uri, this.method); + + return new OkHttpListenableFuture(this.client.newCall(request)); + } + + private static class OkHttpListenableFuture + extends SettableListenableFuture { + + private final Call call; + + public OkHttpListenableFuture(Call call) { + this.call = call; + this.call.enqueue(new Callback() { + @Override + public void onResponse(Response response) { + set(new OkHttpClientHttpResponse(response)); + } + + @Override + public void onFailure(Request request, IOException ex) { + setException(ex); + } + }); + } + + @Override + protected void interruptTask() { + this.call.cancel(); + } + } + +} diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java index fe519f06f5c..538a3fe76d4 100644 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -18,24 +18,12 @@ package org.springframework.http.client; import java.io.IOException; import java.net.URI; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; - -import com.squareup.okhttp.Call; -import com.squareup.okhttp.Callback; -import com.squareup.okhttp.MediaType; + import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.util.StringUtils; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.SettableListenableFuture; /** * {@link ClientHttpRequest} implementation that uses OkHttp to execute requests. @@ -46,7 +34,7 @@ import org.springframework.util.concurrent.SettableListenableFuture; * @author Arjen Poutsma * @since 4.2 */ -class OkHttpClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest implements ClientHttpRequest { +class OkHttpClientHttpRequest extends AbstractBufferingClientHttpRequest { private final OkHttpClient client; @@ -72,73 +60,15 @@ class OkHttpClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest im return this.uri; } - @Override - protected ListenableFuture executeInternal(HttpHeaders headers, byte[] content) - throws IOException { - - MediaType contentType = getContentType(headers); - RequestBody body = (content.length > 0 ? RequestBody.create(contentType, content) : null); - - URL url = this.uri.toURL(); - String methodName = this.method.name(); - Request.Builder builder = new Request.Builder().url(url).method(methodName, body); - - for (Map.Entry> entry : headers.entrySet()) { - String headerName = entry.getKey(); - for (String headerValue : entry.getValue()) { - builder.addHeader(headerName, headerValue); - } - } - Request request = builder.build(); - - return new OkHttpListenableFuture(this.client.newCall(request)); - } - - private MediaType getContentType(HttpHeaders headers) { - String rawContentType = headers.getFirst("Content-Type"); - return (StringUtils.hasText(rawContentType) ? MediaType.parse(rawContentType) : null); - } @Override - public ClientHttpResponse execute() throws IOException { - try { - return executeAsync().get(); - } - catch (InterruptedException ex) { - throw new IOException(ex.getMessage(), ex); - } - catch (ExecutionException ex) { - Throwable cause = ex.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } - throw new IOException(cause.getMessage(), cause); - } - } + protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] content) + throws IOException { + Request request = OkHttpClientHttpRequestFactory + .buildRequest(headers, content, this.uri, this.method); - private static class OkHttpListenableFuture extends SettableListenableFuture { - - private final Call call; - - public OkHttpListenableFuture(Call call) { - this.call = call; - this.call.enqueue(new Callback() { - @Override - public void onResponse(Response response) { - set(new OkHttpClientHttpResponse(response)); - } - @Override - public void onFailure(Request request, IOException ex) { - setException(ex); - } - }); - } - - @Override - protected void interruptTask() { - this.call.cancel(); - } + return new OkHttpClientHttpResponse(this.client.newCall(request).execute()); } } diff --git a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java index c5eabc9bf88..96ed87e6ba5 100644 --- a/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java +++ b/spring-web/src/main/java/org/springframework/http/client/OkHttpClientHttpRequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -16,14 +16,22 @@ package org.springframework.http.client; +import java.net.MalformedURLException; import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; import org.springframework.beans.factory.DisposableBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * {@link ClientHttpRequestFactory} implementation that uses @@ -90,18 +98,40 @@ public class OkHttpClientHttpRequestFactory @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) { - return createRequestInternal(uri, httpMethod); + return new OkHttpClientHttpRequest(this.client, uri, httpMethod); } @Override public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) { - return createRequestInternal(uri, httpMethod); + return new OkHttpAsyncClientHttpRequest(this.client, uri, httpMethod); } - private OkHttpClientHttpRequest createRequestInternal(URI uri, HttpMethod httpMethod) { - return new OkHttpClientHttpRequest(this.client, uri, httpMethod); + static Request buildRequest(HttpHeaders headers, byte[] content, URI uri, + HttpMethod method) throws MalformedURLException { + com.squareup.okhttp.MediaType contentType = getContentType(headers); + RequestBody body = + (content.length > 0 ? RequestBody.create(contentType, content) : null); + + URL url = uri.toURL(); + String methodName = method.name(); + Request.Builder builder = new Request.Builder().url(url).method(methodName, body); + + for (Map.Entry> entry : headers.entrySet()) { + String headerName = entry.getKey(); + for (String headerValue : entry.getValue()) { + builder.addHeader(headerName, headerValue); + } + } + return builder.build(); + } + + private static com.squareup.okhttp.MediaType getContentType(HttpHeaders headers) { + String rawContentType = headers.getFirst(HttpHeaders.CONTENT_TYPE); + return (StringUtils.hasText(rawContentType) ? + com.squareup.okhttp.MediaType.parse(rawContentType) : null); } + @Override public void destroy() throws Exception { if (this.defaultClient) {