mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-10-08 16:19:48 +00:00
Handle error responses in RestClientAdapter
Closes gh-35375
This commit is contained in:
+28
-13
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.web.client.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
@@ -72,13 +73,10 @@ public final class RestClientAdapter implements HttpExchangeAdapter {
|
||||
return newRequest(values).retrieve().toBodilessEntity().getHeaders();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> @Nullable T exchangeForBody(HttpRequestValues values, ParameterizedTypeReference<T> bodyType) {
|
||||
if (bodyType.getType().equals(InputStream.class)) {
|
||||
return (T) newRequest(values).exchange((request, response) -> response.getBody(), false);
|
||||
}
|
||||
return newRequest(values).retrieve().body(bodyType);
|
||||
return (bodyType.getType().equals(InputStream.class) ?
|
||||
exchangeForInputStream(values) : newRequest(values).retrieve().body(bodyType));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,16 +84,23 @@ public final class RestClientAdapter implements HttpExchangeAdapter {
|
||||
return newRequest(values).retrieve().toBodilessEntity();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ResponseEntity<T> exchangeForEntity(HttpRequestValues values, ParameterizedTypeReference<T> bodyType) {
|
||||
if (bodyType.getType().equals(InputStream.class)) {
|
||||
return (ResponseEntity<T>) newRequest(values).exchangeForRequiredValue((request, response) ->
|
||||
ResponseEntity.status(response.getStatusCode())
|
||||
.headers(response.getHeaders())
|
||||
.body(response.getBody()), false);
|
||||
}
|
||||
return newRequest(values).retrieve().toEntity(bodyType);
|
||||
return (bodyType.getType().equals(InputStream.class) ?
|
||||
exchangeForEntityInputStream(values) : newRequest(values).retrieve().toEntity(bodyType));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T exchangeForInputStream(HttpRequestValues values) {
|
||||
return (T) newRequest(values).exchange((request, response) -> getInputStream(response), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> ResponseEntity<T> exchangeForEntityInputStream(HttpRequestValues values) {
|
||||
return (ResponseEntity<T>) newRequest(values).exchangeForRequiredValue((request, response) ->
|
||||
ResponseEntity.status(response.getStatusCode())
|
||||
.headers(response.getHeaders())
|
||||
.body(getInputStream(response)), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -157,6 +162,16 @@ public final class RestClientAdapter implements HttpExchangeAdapter {
|
||||
return bodySpec;
|
||||
}
|
||||
|
||||
private static InputStream getInputStream(
|
||||
RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse response) throws IOException {
|
||||
|
||||
if (response.getStatusCode().isError()) {
|
||||
throw response.createException();
|
||||
}
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link RestClientAdapter} for the given {@link RestClient}.
|
||||
|
||||
+11
@@ -56,6 +56,7 @@ import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.client.ApiVersionInserter;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@@ -69,6 +70,7 @@ import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||
import org.springframework.web.util.UriBuilderFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link HttpServiceProxyFactory} with {@link RestClient}
|
||||
@@ -335,6 +337,15 @@ class RestClientAdapterTests {
|
||||
assertThat(StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8)).isEqualTo("Hello Spring 2!");
|
||||
}
|
||||
|
||||
@Test // gh-35375
|
||||
void getInputStreamWithError() {
|
||||
prepareResponse(builder -> builder.code(400).body("rejected"));
|
||||
|
||||
assertThatThrownBy(() -> initService().getInputStream())
|
||||
.isExactlyInstanceOf(HttpClientErrorException.BadRequest.class)
|
||||
.hasMessage("400 Client Error: \"rejected\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void postOutputStream() throws Exception {
|
||||
prepareResponse(builder ->
|
||||
|
||||
Reference in New Issue
Block a user