Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2002-2017 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.web.client;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.transform.Source;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
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.support.InterceptingHttpAccessor;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.util.AbstractUriTemplateHandler;
import org.springframework.web.util.DefaultUriTemplateHandler;
import org.springframework.web.util.UriTemplateHandler;
/**
* Spring's central class for synchronous client-side HTTP access.
* It simplifies communication with HTTP servers, and enforces RESTful principles.
* It handles HTTP connections, leaving application code to provide URLs
* (with possible template variables) and extract results.
*
*
Note: by default the RestTemplate 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 through the
* {@link #setRequestFactory} property.
*
*
The main entry points of this template are the methods named after the six main HTTP methods:
*
*
HTTP method
RestTemplate methods
*
DELETE
{@link #delete}
*
GET
{@link #getForObject}
*
{@link #getForEntity}
*
HEAD
{@link #headForHeaders}
*
OPTIONS
{@link #optionsForAllow}
*
POST
{@link #postForLocation}
*
{@link #postForObject}
*
PUT
{@link #put}
*
any
{@link #exchange}
*
{@link #execute}
*
*
In addition the {@code exchange} and {@code execute} methods are generalized versions of
* the above methods and can be used to support additional, less frequent combinations (e.g.
* HTTP PATCH, HTTP PUT with response body, etc.). Note however that the underlying HTTP
* library used must also support the desired combination.
*
*
For each HTTP method there are three variants: two accept a URI template string
* and URI variables (array or map) while a third accepts a {@link URI}.
* Note that for URI templates it is assumed encoding is necessary, e.g.
* {@code restTemplate.getForObject("http://example.com/hotel list")} becomes
* {@code "http://example.com/hotel%20list"}. This also means if the URI template
* or URI variables are already encoded, double encoding will occur, e.g.
* {@code http://example.com/hotel%20list} becomes
* {@code http://example.com/hotel%2520list}). To avoid that use a {@code URI} method
* variant to provide (or re-use) a previously encoded URI. To prepare such an URI
* with full control over encoding, consider using
* {@link org.springframework.web.util.UriComponentsBuilder}.
*
*
Internally the template uses {@link HttpMessageConverter} instances to
* convert HTTP messages to and from POJOs. Converters for the main mime types
* are registered by default but you can also register additional converters
* via {@link #setMessageConverters}.
*
*
This template uses a
* {@link org.springframework.http.client.SimpleClientHttpRequestFactory} and a
* {@link DefaultResponseErrorHandler} as default strategies for creating HTTP
* connections or handling HTTP errors, respectively. These defaults can be overridden
* through {@link #setRequestFactory} and {@link #setErrorHandler} respectively.
*
* @author Arjen Poutsma
* @author Brian Clozel
* @author Roy Clarkson
* @author Juergen Hoeller
* @since 3.0
* @see HttpMessageConverter
* @see RequestCallback
* @see ResponseExtractor
* @see ResponseErrorHandler
* @see AsyncRestTemplate
*/
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
private static boolean romePresent =
ClassUtils.isPresent("com.rometools.rome.feed.WireFeed",
RestTemplate.class.getClassLoader());
private static final boolean jaxb2Present =
ClassUtils.isPresent("javax.xml.bind.Binder",
RestTemplate.class.getClassLoader());
private static final boolean jackson2Present =
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
RestTemplate.class.getClassLoader()) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
RestTemplate.class.getClassLoader());
private static final boolean jackson2XmlPresent =
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper",
RestTemplate.class.getClassLoader());
private static final boolean gsonPresent =
ClassUtils.isPresent("com.google.gson.Gson",
RestTemplate.class.getClassLoader());
private final List> messageConverters = new ArrayList>();
private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
private UriTemplateHandler uriTemplateHandler = new DefaultUriTemplateHandler();
private final ResponseExtractor headersExtractor = new HeadersExtractor();
/**
* Create a new instance of the {@link RestTemplate} using default settings.
* Default {@link HttpMessageConverter}s are initialized.
*/
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter());
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
}
else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
}
}
/**
* Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
* @param requestFactory HTTP request factory to use
* @see org.springframework.http.client.SimpleClientHttpRequestFactory
* @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory
*/
public RestTemplate(ClientHttpRequestFactory requestFactory) {
this();
setRequestFactory(requestFactory);
}
/**
* Create a new instance of the {@link RestTemplate} using the given list of
* {@link HttpMessageConverter} to use
* @param messageConverters the list of {@link HttpMessageConverter} to use
* @since 3.2.7
*/
public RestTemplate(List> messageConverters) {
Assert.notEmpty(messageConverters, "At least one HttpMessageConverter required");
this.messageConverters.addAll(messageConverters);
}
/**
* Set the message body converters to use.
*
These converters are used to convert from and to HTTP requests and responses.
*/
public void setMessageConverters(List> messageConverters) {
Assert.notEmpty(messageConverters, "At least one HttpMessageConverter required");
// Take getMessageConverters() List as-is when passed in here
if (this.messageConverters != messageConverters) {
this.messageConverters.clear();
this.messageConverters.addAll(messageConverters);
}
}
/**
* Return the list of message body converters.
*
The returned {@link List} is active and may get appended to.
*/
public List> getMessageConverters() {
return this.messageConverters;
}
/**
* Set the error handler.
*
By default, RestTemplate uses a {@link DefaultResponseErrorHandler}.
*/
public void setErrorHandler(ResponseErrorHandler errorHandler) {
Assert.notNull(errorHandler, "ResponseErrorHandler must not be null");
this.errorHandler = errorHandler;
}
/**
* Return the error handler.
*/
public ResponseErrorHandler getErrorHandler() {
return this.errorHandler;
}
/**
* Configure default URI variable values. This is a shortcut for:
*
* DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler();
* handler.setDefaultUriVariables(...);
*
* RestTemplate restTemplate = new RestTemplate();
* restTemplate.setUriTemplateHandler(handler);
*
* @param defaultUriVariables the default URI variable values
* @since 4.3
*/
public void setDefaultUriVariables(Map defaultUriVariables) {
Assert.isInstanceOf(AbstractUriTemplateHandler.class, this.uriTemplateHandler,
"Can only use this property in conjunction with an AbstractUriTemplateHandler");
((AbstractUriTemplateHandler) this.uriTemplateHandler).setDefaultUriVariables(defaultUriVariables);
}
/**
* Configure the {@link UriTemplateHandler} to use to expand URI templates.
* By default the {@link DefaultUriTemplateHandler} is used which relies on
* Spring's URI template support and exposes several useful properties that
* customize its behavior for encoding and for prepending a common base URL.
* An alternative implementation may be used to plug an external URI
* template library.
* @param handler the URI template handler to use
*/
public void setUriTemplateHandler(UriTemplateHandler handler) {
Assert.notNull(handler, "UriTemplateHandler must not be null");
this.uriTemplateHandler = handler;
}
/**
* Return the configured URI template handler.
*/
public UriTemplateHandler getUriTemplateHandler() {
return this.uriTemplateHandler;
}
// GET
@Override
public T getForObject(String url, Class responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
public T getForObject(String url, Class responseType, Map uriVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
public T getForObject(URI url, Class responseType) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
@Override
public ResponseEntity getForEntity(String url, Class responseType, Object... uriVariables)
throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity getForEntity(String url, Class responseType, Map uriVariables)
throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity getForEntity(URI url, Class responseType) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
// HEAD
@Override
public HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientException {
return execute(url, HttpMethod.HEAD, null, headersExtractor(), uriVariables);
}
@Override
public HttpHeaders headForHeaders(String url, Map uriVariables) throws RestClientException {
return execute(url, HttpMethod.HEAD, null, headersExtractor(), uriVariables);
}
@Override
public HttpHeaders headForHeaders(URI url) throws RestClientException {
return execute(url, HttpMethod.HEAD, null, headersExtractor());
}
// POST
@Override
public URI postForLocation(String url, Object request, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
HttpHeaders headers = execute(url, HttpMethod.POST, requestCallback, headersExtractor(), uriVariables);
return headers.getLocation();
}
@Override
public URI postForLocation(String url, Object request, Map uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
HttpHeaders headers = execute(url, HttpMethod.POST, requestCallback, headersExtractor(), uriVariables);
return headers.getLocation();
}
@Override
public URI postForLocation(URI url, Object request) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
HttpHeaders headers = execute(url, HttpMethod.POST, requestCallback, headersExtractor());
return headers.getLocation();
}
@Override
public T postForObject(String url, Object request, Class responseType, Object... uriVariables)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
@Override
public T postForObject(String url, Object request, Class responseType, Map uriVariables)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
@Override
public T postForObject(URI url, Object request, Class responseType) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters());
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
}
@Override
public ResponseEntity postForEntity(String url, Object request, Class responseType, Object... uriVariables)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity postForEntity(String url, Object request, Class responseType, Map uriVariables)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity postForEntity(URI url, Object request, Class responseType) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, HttpMethod.POST, requestCallback, responseExtractor);
}
// PUT
@Override
public void put(String url, Object request, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
}
@Override
public void put(String url, Object request, Map uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
execute(url, HttpMethod.PUT, requestCallback, null, uriVariables);
}
@Override
public void put(URI url, Object request) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request);
execute(url, HttpMethod.PUT, requestCallback, null);
}
// PATCH
@Override
public T patchForObject(String url, Object request, Class responseType,
Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
}
@Override
public T patchForObject(String url, Object request, Class responseType,
Map uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor, uriVariables);
}
@Override
public T patchForObject(URI url, Object request, Class responseType)
throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(request, responseType);
HttpMessageConverterExtractor responseExtractor =
new HttpMessageConverterExtractor(responseType, getMessageConverters());
return execute(url, HttpMethod.PATCH, requestCallback, responseExtractor);
}
// DELETE
@Override
public void delete(String url, Object... uriVariables) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null, uriVariables);
}
@Override
public void delete(String url, Map uriVariables) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null, uriVariables);
}
@Override
public void delete(URI url) throws RestClientException {
execute(url, HttpMethod.DELETE, null, null);
}
// OPTIONS
@Override
public Set optionsForAllow(String url, Object... uriVariables) throws RestClientException {
ResponseExtractor headersExtractor = headersExtractor();
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, uriVariables);
return headers.getAllow();
}
@Override
public Set optionsForAllow(String url, Map uriVariables) throws RestClientException {
ResponseExtractor headersExtractor = headersExtractor();
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor, uriVariables);
return headers.getAllow();
}
@Override
public Set optionsForAllow(URI url) throws RestClientException {
ResponseExtractor headersExtractor = headersExtractor();
HttpHeaders headers = execute(url, HttpMethod.OPTIONS, null, headersExtractor);
return headers.getAllow();
}
// exchange
@Override
public ResponseEntity exchange(String url, HttpMethod method,
HttpEntity> requestEntity, Class responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity exchange(String url, HttpMethod method,
HttpEntity> requestEntity, Class responseType, Map uriVariables) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity exchange(URI url, HttpMethod method, HttpEntity> requestEntity,
Class responseType) throws RestClientException {
RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(url, method, requestCallback, responseExtractor);
}
@Override
public ResponseEntity exchange(String url, HttpMethod method, HttpEntity> requestEntity,
ParameterizedTypeReference responseType, Object... uriVariables) throws RestClientException {
Type type = responseType.getType();
RequestCallback requestCallback = httpEntityCallback(requestEntity, type);
ResponseExtractor> responseExtractor = responseEntityExtractor(type);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity exchange(String url, HttpMethod method, HttpEntity> requestEntity,
ParameterizedTypeReference responseType, Map uriVariables) throws RestClientException {
Type type = responseType.getType();
RequestCallback requestCallback = httpEntityCallback(requestEntity, type);
ResponseExtractor> responseExtractor = responseEntityExtractor(type);
return execute(url, method, requestCallback, responseExtractor, uriVariables);
}
@Override
public ResponseEntity exchange(URI url, HttpMethod method, HttpEntity> requestEntity,
ParameterizedTypeReference responseType) throws RestClientException {
Type type = responseType.getType();
RequestCallback requestCallback = httpEntityCallback(requestEntity, type);
ResponseExtractor> responseExtractor = responseEntityExtractor(type);
return execute(url, method, requestCallback, responseExtractor);
}
@Override
public ResponseEntity exchange(RequestEntity> requestEntity, Class responseType)
throws RestClientException {
Assert.notNull(requestEntity, "RequestEntity must not be null");
RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
ResponseExtractor> responseExtractor = responseEntityExtractor(responseType);
return execute(requestEntity.getUrl(), requestEntity.getMethod(), requestCallback, responseExtractor);
}
@Override
public ResponseEntity exchange(RequestEntity> requestEntity, ParameterizedTypeReference responseType)
throws RestClientException {
Assert.notNull(requestEntity, "RequestEntity must not be null");
Type type = responseType.getType();
RequestCallback requestCallback = httpEntityCallback(requestEntity, type);
ResponseExtractor> responseExtractor = responseEntityExtractor(type);
return execute(requestEntity.getUrl(), requestEntity.getMethod(), requestCallback, responseExtractor);
}
// general execution
@Override
public T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor responseExtractor, Object... uriVariables) throws RestClientException {
URI expanded = getUriTemplateHandler().expand(url, uriVariables);
return doExecute(expanded, method, requestCallback, responseExtractor);
}
@Override
public T execute(String url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor responseExtractor, Map uriVariables) throws RestClientException {
URI expanded = getUriTemplateHandler().expand(url, uriVariables);
return doExecute(expanded, method, requestCallback, responseExtractor);
}
@Override
public T execute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor responseExtractor) throws RestClientException {
return doExecute(url, method, requestCallback, responseExtractor);
}
/**
* Execute the given method on the provided URI.
*
The {@link 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 doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
ResponseExtractor responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null");
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
else {
return null;
}
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
/**
* Handle the given response, performing appropriate logging and
* invoking the {@link ResponseErrorHandler} if necessary.
*
Can be overridden in subclasses.
* @param url the fully-expanded URL to connect to
* @param method the HTTP method to execute (GET, POST, etc.)
* @param response the resulting {@link ClientHttpResponse}
* @throws IOException if propagated from {@link ResponseErrorHandler}
* @since 4.1.6
* @see #setErrorHandler
*/
protected void handleResponse(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
ResponseErrorHandler errorHandler = getErrorHandler();
boolean hasError = errorHandler.hasError(response);
if (logger.isDebugEnabled()) {
try {
logger.debug(method.name() + " request for \"" + url + "\" resulted in " +
response.getRawStatusCode() + " (" + response.getStatusText() + ")" +
(hasError ? "; invoking error handler" : ""));
}
catch (IOException ex) {
// ignore
}
}
if (hasError) {
errorHandler.handleError(response);
}
}
/**
* 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 RequestCallback acceptHeaderRequestCallback(Class responseType) {
return new AcceptHeaderRequestCallback(responseType);
}
/**
* Returns a request callback implementation that writes the given object to the
* request stream.
*/
protected RequestCallback httpEntityCallback(Object requestBody) {
return new HttpEntityRequestCallback(requestBody);
}
/**
* Returns a request callback implementation that writes the given object to the
* request stream.
*/
protected RequestCallback httpEntityCallback(Object requestBody, Type responseType) {
return new HttpEntityRequestCallback(requestBody, responseType);
}
/**
* Returns a response extractor for {@link ResponseEntity}.
*/
protected ResponseExtractor> responseEntityExtractor(Type responseType) {
return new ResponseEntityResponseExtractor(responseType);
}
/**
* Returns a response extractor for {@link HttpHeaders}.
*/
protected ResponseExtractor headersExtractor() {
return this.headersExtractor;
}
/**
* Request callback implementation that prepares the request's accept headers.
*/
private class AcceptHeaderRequestCallback implements RequestCallback {
private final Type responseType;
private AcceptHeaderRequestCallback(Type responseType) {
this.responseType = responseType;
}
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
if (this.responseType != null) {
Class> responseClass = null;
if (this.responseType instanceof Class) {
responseClass = (Class>) this.responseType;
}
List allSupportedMediaTypes = new ArrayList();
for (HttpMessageConverter> converter : getMessageConverters()) {
if (responseClass != null) {
if (converter.canRead(responseClass, null)) {
allSupportedMediaTypes.addAll(getSupportedMediaTypes(converter));
}
}
else if (converter instanceof GenericHttpMessageConverter) {
GenericHttpMessageConverter> genericConverter = (GenericHttpMessageConverter>) converter;
if (genericConverter.canRead(this.responseType, null, null)) {
allSupportedMediaTypes.addAll(getSupportedMediaTypes(converter));
}
}
}
if (!allSupportedMediaTypes.isEmpty()) {
MediaType.sortBySpecificity(allSupportedMediaTypes);
if (logger.isDebugEnabled()) {
logger.debug("Setting request Accept header to " + allSupportedMediaTypes);
}
request.getHeaders().setAccept(allSupportedMediaTypes);
}
}
}
private List getSupportedMediaTypes(HttpMessageConverter> messageConverter) {
List supportedMediaTypes = messageConverter.getSupportedMediaTypes();
List result = new ArrayList(supportedMediaTypes.size());
for (MediaType supportedMediaType : supportedMediaTypes) {
if (supportedMediaType.getCharset() != null) {
supportedMediaType =
new MediaType(supportedMediaType.getType(), supportedMediaType.getSubtype());
}
result.add(supportedMediaType);
}
return result;
}
}
/**
* Request callback implementation that writes the given object to the request stream.
*/
private class HttpEntityRequestCallback extends AcceptHeaderRequestCallback {
private final HttpEntity> requestEntity;
private HttpEntityRequestCallback(Object requestBody) {
this(requestBody, null);
}
private HttpEntityRequestCallback(Object requestBody, Type responseType) {
super(responseType);
if (requestBody instanceof HttpEntity) {
this.requestEntity = (HttpEntity>) requestBody;
}
else if (requestBody != null) {
this.requestEntity = new HttpEntity