Use IntrospectingClientHttpResponse in RestClient
This commit ensures that the RestClient uses the IntrospectingClientHttpResponse to verify whether the response has a body, and return null if it does not. See gh-12671 Closes gh-31719
This commit is contained in:
parent
0dbb0f5c14
commit
d204dd2dbe
|
@ -184,32 +184,40 @@ final class DefaultRestClient implements RestClient {
|
|||
return new DefaultRestClientBuilder(this.builder);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private <T> T readWithMessageConverters(ClientHttpResponse clientResponse, Runnable callback, Type bodyType, Class<T> bodyClass) {
|
||||
private <T> T readWithMessageConverters(ClientHttpResponse clientResponse, Runnable callback, Type bodyType,
|
||||
Class<T> bodyClass) {
|
||||
|
||||
MediaType contentType = getContentType(clientResponse);
|
||||
|
||||
try (clientResponse) {
|
||||
callback.run();
|
||||
|
||||
IntrospectingClientHttpResponse responseWrapper = new IntrospectingClientHttpResponse(clientResponse);
|
||||
if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
if (messageConverter instanceof GenericHttpMessageConverter genericHttpMessageConverter) {
|
||||
if (genericHttpMessageConverter.canRead(bodyType, null, contentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading to [" + ResolvableType.forType(bodyType) + "]");
|
||||
}
|
||||
return (T) genericHttpMessageConverter.read(bodyType, null, clientResponse);
|
||||
return (T) genericHttpMessageConverter.read(bodyType, null, responseWrapper);
|
||||
}
|
||||
}
|
||||
if (messageConverter.canRead(bodyClass, contentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading to [" + bodyClass.getName() + "] as \"" + contentType + "\"");
|
||||
}
|
||||
return (T) messageConverter.read((Class)bodyClass, clientResponse);
|
||||
return (T) messageConverter.read((Class)bodyClass, responseWrapper);
|
||||
}
|
||||
}
|
||||
throw new UnknownContentTypeException(bodyType, contentType,
|
||||
clientResponse.getStatusCode(), clientResponse.getStatusText(),
|
||||
clientResponse.getHeaders(), RestClientUtils.getBody(clientResponse));
|
||||
responseWrapper.getStatusCode(), responseWrapper.getStatusText(),
|
||||
responseWrapper.getHeaders(), RestClientUtils.getBody(responseWrapper));
|
||||
}
|
||||
catch (UncheckedIOException | IOException | HttpMessageNotReadableException ex) {
|
||||
throw new RestClientException("Error while extracting response for type [" +
|
||||
|
@ -585,11 +593,13 @@ final class DefaultRestClient implements RestClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T body(Class<T> bodyType) {
|
||||
return readBody(bodyType, bodyType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T body(ParameterizedTypeReference<T> bodyType) {
|
||||
Type type = bodyType.getType();
|
||||
Class<T> bodyClass = bodyClass(type);
|
||||
|
@ -637,6 +647,7 @@ final class DefaultRestClient implements RestClient {
|
|||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private <T> T readBody(Type bodyType, Class<T> bodyClass) {
|
||||
return DefaultRestClient.this.readWithMessageConverters(this.clientResponse, this::applyStatusHandlers,
|
||||
bodyType, bodyClass);
|
||||
|
|
|
@ -348,6 +348,23 @@ class RestClientIntegrationTests {
|
|||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@ParameterizedRestClientTest
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
void retrieveJsonEmpty(ClientHttpRequestFactory requestFactory) {
|
||||
startServer(requestFactory);
|
||||
|
||||
prepareResponse(response -> response
|
||||
.setResponseCode(200)
|
||||
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE));
|
||||
|
||||
Pojo result = this.restClient.get()
|
||||
.uri("/null")
|
||||
.retrieve()
|
||||
.body(Pojo.class);
|
||||
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@ParameterizedRestClientTest
|
||||
void retrieve404(ClientHttpRequestFactory requestFactory) {
|
||||
startServer(requestFactory);
|
||||
|
|
Loading…
Reference in New Issue