diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java index c148c80ee07..f818e47568f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultClientResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -157,35 +157,32 @@ class DefaultClientResponse implements ClientResponse { @Override public Mono releaseBody() { - return body(BodyExtractors.toDataBuffers()) - .map(DataBufferUtils::release) - .then(); + return body(BodyExtractors.toDataBuffers()).map(DataBufferUtils::release).then(); } @Override public Mono> toBodilessEntity() { - return releaseBody() - .then(WebClientUtils.toEntity(this, Mono.empty())); + return releaseBody().then(WebClientUtils.mapToEntity(this, Mono.empty())); } @Override public Mono> toEntity(Class bodyType) { - return WebClientUtils.toEntity(this, bodyToMono(bodyType)); + return WebClientUtils.mapToEntity(this, bodyToMono(bodyType)); } @Override public Mono> toEntity(ParameterizedTypeReference bodyTypeReference) { - return WebClientUtils.toEntity(this, bodyToMono(bodyTypeReference)); + return WebClientUtils.mapToEntity(this, bodyToMono(bodyTypeReference)); } @Override public Mono>> toEntityList(Class elementClass) { - return WebClientUtils.toEntityList(this, bodyToFlux(elementClass)); + return WebClientUtils.mapToEntityList(this, bodyToFlux(elementClass)); } @Override public Mono>> toEntityList(ParameterizedTypeReference elementTypeRef) { - return WebClientUtils.toEntityList(this, bodyToFlux(elementTypeRef)); + return WebClientUtils.mapToEntityList(this, bodyToFlux(elementTypeRef)); } @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java index 587c335dcb4..b12d6370155 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -546,34 +546,35 @@ class DefaultWebClient implements WebClient { @Override public Mono> toEntity(Class bodyClass) { return this.responseMono.flatMap(response -> - WebClientUtils.toEntity(response, handleBodyMono(response, response.bodyToMono(bodyClass)))); + WebClientUtils.mapToEntity(response, + handleBodyMono(response, response.bodyToMono(bodyClass)))); } @Override - public Mono> toEntity(ParameterizedTypeReference bodyTypeReference) { + public Mono> toEntity(ParameterizedTypeReference bodyTypeRef) { return this.responseMono.flatMap(response -> - WebClientUtils.toEntity(response, - handleBodyMono(response, response.bodyToMono(bodyTypeReference)))); + WebClientUtils.mapToEntity(response, + handleBodyMono(response, response.bodyToMono(bodyTypeRef)))); } @Override public Mono>> toEntityList(Class elementClass) { return this.responseMono.flatMap(response -> - WebClientUtils.toEntityList(response, + WebClientUtils.mapToEntityList(response, handleBodyFlux(response, response.bodyToFlux(elementClass)))); } @Override public Mono>> toEntityList(ParameterizedTypeReference elementTypeRef) { return this.responseMono.flatMap(response -> - WebClientUtils.toEntityList(response, + WebClientUtils.mapToEntityList(response, handleBodyFlux(response, response.bodyToFlux(elementTypeRef)))); } @Override public Mono> toBodilessEntity() { return this.responseMono.flatMap(response -> - WebClientUtils.toEntity(response, handleBodyMono(response, Mono.empty())) + WebClientUtils.mapToEntity(response, handleBodyMono(response, Mono.empty())) .doOnNext(entity -> response.releaseBody()) // body is drained in other cases ); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientUtils.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientUtils.java index f6494f1544d..ac05b7b0481 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientUtils.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/WebClientUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -22,10 +22,7 @@ import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.lang.Nullable; /** * Internal methods shared between {@link DefaultWebClient} and {@link DefaultClientResponse}. @@ -35,37 +32,28 @@ import org.springframework.lang.Nullable; */ abstract class WebClientUtils { + private static final String VALUE_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n"; + + /** - * Create a delayed {@link ResponseEntity} from the given response and body. + * Map the given response to a single value {@code ResponseEntity}. */ - public static Mono> toEntity(ClientResponse response, Mono bodyMono) { - return Mono.defer(() -> { - HttpHeaders headers = response.headers().asHttpHeaders(); - int status = response.rawStatusCode(); - return bodyMono - .map(body -> createEntity(body, headers, status)) - .switchIfEmpty(Mono.fromCallable( () -> createEntity(null, headers, status))); - }); + @SuppressWarnings("unchecked") + public static Mono> mapToEntity(ClientResponse response, Mono bodyMono) { + return ((Mono) bodyMono).defaultIfEmpty(VALUE_NONE).map(body -> + ResponseEntity.status(response.rawStatusCode()) + .headers(response.headers().asHttpHeaders()) + .body(body != VALUE_NONE ? (T) body : null)); } /** - * Create a delayed {@link ResponseEntity} list from the given response and body. + * Map the given response to a {@code ResponseEntity>}. */ - public static Mono>> toEntityList(ClientResponse response, Publisher body) { - return Mono.defer(() -> { - HttpHeaders headers = response.headers().asHttpHeaders(); - int status = response.rawStatusCode(); - return Flux.from(body) - .collectList() - .map(list -> createEntity(list, headers, status)); - }); - } - - public static ResponseEntity createEntity(@Nullable T body, HttpHeaders headers, int status) { - HttpStatus resolvedStatus = HttpStatus.resolve(status); - return resolvedStatus != null - ? new ResponseEntity<>(body, headers, resolvedStatus) - : ResponseEntity.status(status).headers(headers).body(body); + public static Mono>> mapToEntityList(ClientResponse response, Publisher body) { + return Flux.from(body).collectList().map(list -> + ResponseEntity.status(response.rawStatusCode()) + .headers(response.headers().asHttpHeaders()) + .body(list)); } }