/*
 * Copyright 2002-2018 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
 *
 *      https://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.web.client;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureAdapter;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriTemplateHandler;

Spring's central class for asynchronous client-side HTTP access. Exposes similar methods as RestTemplate, but returns ListenableFuture wrappers as opposed to concrete results.

The AsyncRestTemplate exposes a synchronous RestTemplate via the getRestOperations() method and shares its error handler and message converters with that RestTemplate.

Note: by default AsyncRestTemplate relies on standard JDK facilities to establish HTTP connections. You can switch to use a different HTTP library such as Apache HttpComponents, Netty, and OkHttp by using a constructor accepting an AsyncClientHttpRequestFactory.

For more information, please refer to the RestTemplate API documentation.

Author:Arjen Poutsma
See Also:
Since:4.0
Deprecated:as of Spring 5.0, in favor of WebClient
/** * <strong>Spring's central class for asynchronous client-side HTTP access.</strong> * Exposes similar methods as {@link RestTemplate}, but returns {@link ListenableFuture} * wrappers as opposed to concrete results. * * <p>The {@code AsyncRestTemplate} exposes a synchronous {@link RestTemplate} via the * {@link #getRestOperations()} method and shares its {@linkplain #setErrorHandler error handler} * and {@linkplain #setMessageConverters message converters} with that {@code RestTemplate}. * * <p><strong>Note:</strong> by default {@code AsyncRestTemplate} relies on * standard JDK facilities to establish HTTP connections. You can switch to use * a different HTTP library such as Apache HttpComponents, Netty, and OkHttp by * using a constructor accepting an {@link org.springframework.http.client.AsyncClientHttpRequestFactory}. * * <p>For more information, please refer to the {@link RestTemplate} API documentation. * * @author Arjen Poutsma * @since 4.0 * @see RestTemplate * @deprecated as of Spring 5.0, in favor of {@link org.springframework.web.reactive.function.client.WebClient} */
@Deprecated public class AsyncRestTemplate extends org.springframework.http.client.support.InterceptingAsyncHttpAccessor implements AsyncRestOperations { private final RestTemplate syncTemplate;
Create a new instance of the AsyncRestTemplate using default settings.

This constructor uses a SimpleClientHttpRequestFactory in combination with a SimpleAsyncTaskExecutor for asynchronous execution.

/** * Create a new instance of the {@code AsyncRestTemplate} using default settings. * <p>This constructor uses a {@link SimpleClientHttpRequestFactory} in combination * with a {@link SimpleAsyncTaskExecutor} for asynchronous execution. */
public AsyncRestTemplate() { this(new SimpleAsyncTaskExecutor()); }
Create a new instance of the AsyncRestTemplate using the given AsyncTaskExecutor.

This constructor uses a SimpleClientHttpRequestFactory in combination with the given AsyncTaskExecutor for asynchronous execution.

/** * Create a new instance of the {@code AsyncRestTemplate} using the given * {@link AsyncTaskExecutor}. * <p>This constructor uses a {@link SimpleClientHttpRequestFactory} in combination * with the given {@code AsyncTaskExecutor} for asynchronous execution. */
public AsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor) { Assert.notNull(taskExecutor, "AsyncTaskExecutor must not be null"); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setTaskExecutor(taskExecutor); this.syncTemplate = new RestTemplate(requestFactory); setAsyncRequestFactory(requestFactory); }
Create a new instance of the AsyncRestTemplate using the given AsyncClientHttpRequestFactory.

This constructor will cast the given asynchronous AsyncClientHttpRequestFactory to a ClientHttpRequestFactory. Since all implementations of ClientHttpRequestFactory provided in Spring also implement AsyncClientHttpRequestFactory, this should not result in a ClassCastException.

/** * Create a new instance of the {@code AsyncRestTemplate} using the given * {@link org.springframework.http.client.AsyncClientHttpRequestFactory}. * <p>This constructor will cast the given asynchronous * {@code AsyncClientHttpRequestFactory} to a {@link ClientHttpRequestFactory}. Since * all implementations of {@code ClientHttpRequestFactory} provided in Spring also * implement {@code AsyncClientHttpRequestFactory}, this should not result in a * {@code ClassCastException}. */
public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory) { this(asyncRequestFactory, (ClientHttpRequestFactory) asyncRequestFactory); }
Creates a new instance of the AsyncRestTemplate using the given asynchronous and synchronous request factories.
Params:
  • asyncRequestFactory – the asynchronous request factory
  • syncRequestFactory – the synchronous request factory
/** * Creates a new instance of the {@code AsyncRestTemplate} using the given * asynchronous and synchronous request factories. * @param asyncRequestFactory the asynchronous request factory * @param syncRequestFactory the synchronous request factory */
public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory, ClientHttpRequestFactory syncRequestFactory) { this(asyncRequestFactory, new RestTemplate(syncRequestFactory)); }
Create a new instance of the AsyncRestTemplate using the given AsyncClientHttpRequestFactory and synchronous RestTemplate.
Params:
  • requestFactory – the asynchronous request factory to use
  • restTemplate – the synchronous template to use
/** * Create a new instance of the {@code AsyncRestTemplate} using the given * {@link org.springframework.http.client.AsyncClientHttpRequestFactory} and synchronous {@link RestTemplate}. * @param requestFactory the asynchronous request factory to use * @param restTemplate the synchronous template to use */
public AsyncRestTemplate(org.springframework.http.client.AsyncClientHttpRequestFactory requestFactory, RestTemplate restTemplate) { Assert.notNull(restTemplate, "RestTemplate must not be null"); this.syncTemplate = restTemplate; setAsyncRequestFactory(requestFactory); }
Set the error handler.

By default, AsyncRestTemplate uses a DefaultResponseErrorHandler.

/** * Set the error handler. * <p>By default, AsyncRestTemplate uses a * {@link org.springframework.web.client.DefaultResponseErrorHandler}. */
public void setErrorHandler(ResponseErrorHandler errorHandler) { this.syncTemplate.setErrorHandler(errorHandler); }
Return the error handler.
/** * Return the error handler. */
public ResponseErrorHandler getErrorHandler() { return this.syncTemplate.getErrorHandler(); }
Configure default URI variable values. This is a shortcut for:
DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler();
handler.setDefaultUriVariables(...);
AsyncRestTemplate restTemplate = new AsyncRestTemplate();
restTemplate.setUriTemplateHandler(handler);
Params:
  • defaultUriVariables – the default URI variable values
Since:4.3
/** * Configure default URI variable values. This is a shortcut for: * <pre class="code"> * DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler(); * handler.setDefaultUriVariables(...); * * AsyncRestTemplate restTemplate = new AsyncRestTemplate(); * restTemplate.setUriTemplateHandler(handler); * </pre> * @param defaultUriVariables the default URI variable values * @since 4.3 */
@SuppressWarnings("deprecation") public void setDefaultUriVariables(Map<String, ?> defaultUriVariables) { UriTemplateHandler handler = this.syncTemplate.getUriTemplateHandler(); if (handler instanceof DefaultUriBuilderFactory) { ((DefaultUriBuilderFactory) handler).setDefaultUriVariables(defaultUriVariables); } else if (handler instanceof org.springframework.web.util.AbstractUriTemplateHandler) { ((org.springframework.web.util.AbstractUriTemplateHandler) handler) .setDefaultUriVariables(defaultUriVariables); } else { throw new IllegalArgumentException( "This property is not supported with the configured UriTemplateHandler."); } }
This property has the same purpose as the corresponding property on the RestTemplate. For more details see RestTemplate.setUriTemplateHandler.
Params:
  • handler – the URI template handler to use
/** * This property has the same purpose as the corresponding property on the * {@code RestTemplate}. For more details see * {@link RestTemplate#setUriTemplateHandler}. * @param handler the URI template handler to use */
public void setUriTemplateHandler(UriTemplateHandler handler) { this.syncTemplate.setUriTemplateHandler(handler); }
Return the configured URI template handler.
/** * Return the configured URI template handler. */
public UriTemplateHandler getUriTemplateHandler() { return this.syncTemplate.getUriTemplateHandler(); } @Override public RestOperations getRestOperations() { return this.syncTemplate; }
Set the message body converters to use.

These converters are used to convert from and to HTTP requests and responses.

/** * Set the message body converters to use. * <p>These converters are used to convert from and to HTTP requests and responses. */
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) { this.syncTemplate.setMessageConverters(messageConverters); }
Return the message body converters.
/** * Return the message body converters. */
public List<HttpMessageConverter<?>> getMessageConverters() { return this.syncTemplate.getMessageConverters(); } // GET @Override public <T> ListenableFuture<ResponseEntity<T>> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> getForEntity(URI url, Class<T> responseType) throws RestClientException { AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.GET, requestCallback, responseExtractor); } // HEAD @Override public ListenableFuture<HttpHeaders> headForHeaders(String url, Object... uriVariables) throws RestClientException { ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor(); return execute(url, HttpMethod.HEAD, null, headersExtractor, uriVariables); } @Override public ListenableFuture<HttpHeaders> headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientException { ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor(); return execute(url, HttpMethod.HEAD, null, headersExtractor, uriVariables); } @Override public ListenableFuture<HttpHeaders> headForHeaders(URI url) throws RestClientException { ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor(); return execute(url, HttpMethod.HEAD, null, headersExtractor); } // POST @Override public ListenableFuture<URI> postForLocation(String url, @Nullable HttpEntity<?> request, Object... uriVars) throws RestClientException { AsyncRequestCallback callback = httpEntityCallback(request); ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.POST, callback, extractor, uriVars); return adaptToLocationHeader(future); } @Override public ListenableFuture<URI> postForLocation(String url, @Nullable HttpEntity<?> request, Map<String, ?> uriVars) throws RestClientException { AsyncRequestCallback callback = httpEntityCallback(request); ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.POST, callback, extractor, uriVars); return adaptToLocationHeader(future); } @Override public ListenableFuture<URI> postForLocation(URI url, @Nullable HttpEntity<?> request) throws RestClientException { AsyncRequestCallback callback = httpEntityCallback(request); ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.POST, callback, extractor); return adaptToLocationHeader(future); } private static ListenableFuture<URI> adaptToLocationHeader(ListenableFuture<HttpHeaders> future) { return new ListenableFutureAdapter<URI, HttpHeaders>(future) { @Override @Nullable protected URI adapt(HttpHeaders headers) throws ExecutionException { return headers.getLocation(); } }; } @Override public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, @Nullable HttpEntity<?> request, Class<T> responseType, Object... uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> postForEntity(String url, @Nullable HttpEntity<?> request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> postForEntity(URI url, @Nullable HttpEntity<?> request, Class<T> responseType) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.POST, requestCallback, responseExtractor); } // PUT @Override public ListenableFuture<?> put(String url, @Nullable HttpEntity<?> request, Object... uriVars) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request); return execute(url, HttpMethod.PUT, requestCallback, null, uriVars); } @Override public ListenableFuture<?> put(String url, @Nullable HttpEntity<?> request, Map<String, ?> uriVars) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request); return execute(url, HttpMethod.PUT, requestCallback, null, uriVars); } @Override public ListenableFuture<?> put(URI url, @Nullable HttpEntity<?> request) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request); return execute(url, HttpMethod.PUT, requestCallback, null); } // DELETE @Override public ListenableFuture<?> delete(String url, Object... uriVariables) throws RestClientException { return execute(url, HttpMethod.DELETE, null, null, uriVariables); } @Override public ListenableFuture<?> delete(String url, Map<String, ?> uriVariables) throws RestClientException { return execute(url, HttpMethod.DELETE, null, null, uriVariables); } @Override public ListenableFuture<?> delete(URI url) throws RestClientException { return execute(url, HttpMethod.DELETE, null, null); } // OPTIONS @Override public ListenableFuture<Set<HttpMethod>> optionsForAllow(String url, Object... uriVars) throws RestClientException { ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.OPTIONS, null, extractor, uriVars); return adaptToAllowHeader(future); } @Override public ListenableFuture<Set<HttpMethod>> optionsForAllow(String url, Map<String, ?> uriVars) throws RestClientException { ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.OPTIONS, null, extractor, uriVars); return adaptToAllowHeader(future); } @Override public ListenableFuture<Set<HttpMethod>> optionsForAllow(URI url) throws RestClientException { ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.OPTIONS, null, extractor); return adaptToAllowHeader(future); } private static ListenableFuture<Set<HttpMethod>> adaptToAllowHeader(ListenableFuture<HttpHeaders> future) { return new ListenableFutureAdapter<Set<HttpMethod>, HttpHeaders>(future) { @Override protected Set<HttpMethod> adapt(HttpHeaders headers) throws ExecutionException { return headers.getAllow(); } }; } // exchange @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, method, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, method, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, method, requestCallback, responseExtractor); } @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException { Type type = responseType.getType(); AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type); return execute(url, method, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException { Type type = responseType.getType(); AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type); return execute(url, method, requestCallback, responseExtractor, uriVariables); } @Override public <T> ListenableFuture<ResponseEntity<T>> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType) throws RestClientException { Type type = responseType.getType(); AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, type); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(type); return execute(url, method, requestCallback, responseExtractor); } // general execution @Override public <T> ListenableFuture<T> execute(String url, HttpMethod method, @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException { URI expanded = getUriTemplateHandler().expand(url, uriVariables); return doExecute(expanded, method, requestCallback, responseExtractor); } @Override public <T> ListenableFuture<T> execute(String url, HttpMethod method, @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables) throws RestClientException { URI expanded = getUriTemplateHandler().expand(url, uriVariables); return doExecute(expanded, method, requestCallback, responseExtractor); } @Override public <T> ListenableFuture<T> execute(URI url, HttpMethod method, @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException { return doExecute(url, method, requestCallback, responseExtractor); }
Execute the given method on the provided URI. The ClientHttpRequest is processed using the RequestCallback; the response with the ResponseExtractor.
Params:
  • url – the fully-expanded URL to connect to
  • method – the HTTP method to execute (GET, POST, etc.)
  • requestCallback – object that prepares the request (can be null)
  • responseExtractor – object that extracts the return value from the response (can be null)
Returns:an arbitrary object, as returned by the ResponseExtractor
/** * Execute the given method on the provided URI. The * {@link org.springframework.http.client.ClientHttpRequest} * is processed using the {@link RequestCallback}; the response with * the {@link ResponseExtractor}. * @param url the fully-expanded URL to connect to * @param method the HTTP method to execute (GET, POST, etc.) * @param requestCallback object that prepares the request (can be {@code null}) * @param responseExtractor object that extracts the return value from the response (can * be {@code null}) * @return an arbitrary object, as returned by the {@link ResponseExtractor} */
protected <T> ListenableFuture<T> doExecute(URI url, HttpMethod method, @Nullable AsyncRequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException { Assert.notNull(url, "'url' must not be null"); Assert.notNull(method, "'method' must not be null"); try { org.springframework.http.client.AsyncClientHttpRequest request = createAsyncRequest(url, method); if (requestCallback != null) { requestCallback.doWithRequest(request); } ListenableFuture<ClientHttpResponse> responseFuture = request.executeAsync(); return new ResponseExtractorFuture<>(method, url, responseFuture, responseExtractor); } catch (IOException ex) { throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + url + "\":" + ex.getMessage(), ex); } } private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) { if (logger.isDebugEnabled()) { try { logger.debug("Async " + method.name() + " request for \"" + url + "\" resulted in " + response.getRawStatusCode() + " (" + response.getStatusText() + ")"); } catch (IOException ex) { // ignore } } } private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException { if (logger.isWarnEnabled()) { try { logger.warn("Async " + method.name() + " request for \"" + url + "\" resulted in " + response.getRawStatusCode() + " (" + response.getStatusText() + "); invoking error handler"); } catch (IOException ex) { // ignore } } getErrorHandler().handleError(url, method, response); }
Returns a request callback implementation that prepares the request Accept headers based on the given response type and configured message converters.
/** * Returns a request callback implementation that prepares the request {@code Accept} * headers based on the given response type and configured {@linkplain * #getMessageConverters() message converters}. */
protected <T> AsyncRequestCallback acceptHeaderRequestCallback(Class<T> responseType) { return new AsyncRequestCallbackAdapter(this.syncTemplate.acceptHeaderRequestCallback(responseType)); }
Returns a request callback implementation that writes the given object to the request stream.
/** * Returns a request callback implementation that writes the given object to the * request stream. */
protected <T> AsyncRequestCallback httpEntityCallback(@Nullable HttpEntity<T> requestBody) { return new AsyncRequestCallbackAdapter(this.syncTemplate.httpEntityCallback(requestBody)); }
Returns a request callback implementation that writes the given object to the request stream.
/** * Returns a request callback implementation that writes the given object to the * request stream. */
protected <T> AsyncRequestCallback httpEntityCallback(@Nullable HttpEntity<T> request, Type responseType) { return new AsyncRequestCallbackAdapter(this.syncTemplate.httpEntityCallback(request, responseType)); }
Returns a response extractor for ResponseEntity.
/** * Returns a response extractor for {@link ResponseEntity}. */
protected <T> ResponseExtractor<ResponseEntity<T>> responseEntityExtractor(Type responseType) { return this.syncTemplate.responseEntityExtractor(responseType); }
Returns a response extractor for HttpHeaders.
/** * Returns a response extractor for {@link HttpHeaders}. */
protected ResponseExtractor<HttpHeaders> headersExtractor() { return this.syncTemplate.headersExtractor(); } /** * Future returned from * {@link #doExecute(URI, HttpMethod, AsyncRequestCallback, ResponseExtractor)}. */ private class ResponseExtractorFuture<T> extends ListenableFutureAdapter<T, ClientHttpResponse> { private final HttpMethod method; private final URI url; @Nullable private final ResponseExtractor<T> responseExtractor; public ResponseExtractorFuture(HttpMethod method, URI url, ListenableFuture<ClientHttpResponse> clientHttpResponseFuture, @Nullable ResponseExtractor<T> responseExtractor) { super(clientHttpResponseFuture); this.method = method; this.url = url; this.responseExtractor = responseExtractor; } @Override @Nullable protected final T adapt(ClientHttpResponse response) throws ExecutionException { try { if (!getErrorHandler().hasError(response)) { logResponseStatus(this.method, this.url, response); } else { handleResponseError(this.method, this.url, response); } return convertResponse(response); } catch (Throwable ex) { throw new ExecutionException(ex); } finally { response.close(); } } @Nullable protected T convertResponse(ClientHttpResponse response) throws IOException { return (this.responseExtractor != null ? this.responseExtractor.extractData(response) : null); } }
Adapts a RequestCallback to the AsyncRequestCallback interface.
/** * Adapts a {@link RequestCallback} to the {@link AsyncRequestCallback} interface. */
private static class AsyncRequestCallbackAdapter implements AsyncRequestCallback { private final RequestCallback adaptee;
Create a new AsyncRequestCallbackAdapter from the given RequestCallback.
Params:
  • requestCallback – the callback to base this adapter on
/** * Create a new {@code AsyncRequestCallbackAdapter} from the given * {@link RequestCallback}. * @param requestCallback the callback to base this adapter on */
public AsyncRequestCallbackAdapter(RequestCallback requestCallback) { this.adaptee = requestCallback; } @Override public void doWithRequest(final org.springframework.http.client.AsyncClientHttpRequest request) throws IOException { this.adaptee.doWithRequest(new ClientHttpRequest() { @Override public ClientHttpResponse execute() throws IOException { throw new UnsupportedOperationException("execute not supported"); } @Override public OutputStream getBody() throws IOException { return request.getBody(); } @Override @Nullable public HttpMethod getMethod() { return request.getMethod(); } @Override public String getMethodValue() { return request.getMethodValue(); } @Override public URI getURI() { return request.getURI(); } @Override public HttpHeaders getHeaders() { return request.getHeaders(); } }); } } }