Browse Source

Use ByteArrayDecoder in DefaultClientResponse::createException

This commit changes DefaultClientResponse::createException to use
the ByteArrayDecoder, instead of converting to DataBuffers and
turning these into a byte array.

Closes gh-27666
pull/27832/head
Arjen Poutsma 3 years ago
parent
commit
9197f15a30
  1. 8
      spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java
  2. 25
      spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java

8
spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java

@ -195,13 +195,7 @@ class DefaultClientResponse implements ClientResponse { @@ -195,13 +195,7 @@ class DefaultClientResponse implements ClientResponse {
@Override
public Mono<WebClientResponseException> createException() {
return DataBufferUtils.join(body(BodyExtractors.toDataBuffers()))
.map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
return bytes;
})
return bodyToMono(byte[].class)
.defaultIfEmpty(EMPTY)
.onErrorReturn(ex -> !(ex instanceof Error), EMPTY)
.map(bodyBytes -> {

25
spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultClientResponseTests.java

@ -30,6 +30,7 @@ import reactor.core.publisher.Flux; @@ -30,6 +30,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.codec.ByteArrayDecoder;
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBuffer;
@ -48,6 +49,7 @@ import org.springframework.util.MultiValueMap; @@ -48,6 +49,7 @@ import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
@ -328,6 +330,29 @@ public class DefaultClientResponseTests { @@ -328,6 +330,29 @@ public class DefaultClientResponseTests {
assertThat(result.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_PLAIN);
}
@Test
public void createException() {
byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8);
DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes));
Flux<DataBuffer> body = Flux.just(dataBuffer);
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
given(mockResponse.getStatusCode()).willReturn(HttpStatus.NOT_FOUND);
given(mockResponse.getRawStatusCode()).willReturn(HttpStatus.NOT_FOUND.value());
given(mockResponse.getBody()).willReturn(body);
List<HttpMessageReader<?>> messageReaders = Collections.singletonList(
new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
given(mockExchangeStrategies.messageReaders()).willReturn(messageReaders);
Mono<WebClientResponseException> resultMono = defaultClientResponse.createException();
WebClientResponseException exception = resultMono.block();
assertThat(exception.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(exception.getMessage()).isEqualTo("404 Not Found");
assertThat(exception.getHeaders()).containsExactly(entry("Content-Type",
Collections.singletonList("text/plain")));
assertThat(exception.getResponseBodyAsByteArray()).isEqualTo(bytes);
}
private void mockTextPlainResponse(Flux<DataBuffer> body) {
httpHeaders.setContentType(MediaType.TEXT_PLAIN);

Loading…
Cancel
Save