From 2909de88297971fcdddeccfcdfb3a71c3b2f8b84 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 10 Jul 2019 16:20:20 +0200 Subject: [PATCH] Remove ServerWebExchange::getParts and ServerRequest::parts Revert to state before DefaultMultipartMessageReader --- .../function/server/MockServerRequest.java | 7 ---- .../web/server/ServerWebExchange.java | 15 -------- .../server/ServerWebExchangeDecorator.java | 6 ---- .../adapter/DefaultServerWebExchange.java | 36 ++++++------------- .../function/server/DefaultServerRequest.java | 5 --- .../server/DefaultServerRequestBuilder.java | 35 ++++++------------ .../function/server/RequestPredicates.java | 5 --- .../function/server/ServerRequest.java | 14 -------- .../server/support/ServerRequestWrapper.java | 5 --- .../function/MultipartIntegrationTests.java | 7 ++-- .../function/server/MockServerRequest.java | 7 ---- 11 files changed, 26 insertions(+), 116 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java index 04c52fbfb8..0ae85abbe1 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java @@ -249,13 +249,6 @@ public final class MockServerRequest implements ServerRequest { return (Mono>) this.body; } - @Override - @SuppressWarnings("unchecked") - public Flux parts() { - Assert.state(this.body != null, "No body"); - return (Flux) this.body; - } - @Override public ServerWebExchange exchange() { Assert.state(this.exchange != null, "No exchange"); diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java index 0b02f63f2e..d8cef56757 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchange.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.context.ApplicationContext; @@ -139,23 +138,9 @@ public interface ServerWebExchange { * cached so that this method is safe to call more than once. *

Note:the {@linkplain Part#content() contents} of each * part is not cached, and can only be read once. - * @see #getParts() */ Mono> getMultipartData(); - /** - * Return the parts of a multipart request if the Content-Type is - * {@code "multipart/form-data"} or an empty flux otherwise. - *

Note: calling this method causes the request body to - * be read and parsed in full and the resulting {@code Flux} is - * cached so that this method is safe to call more than once. - *

Note:the {@linkplain Part#content() contents} of each - * part is not cached, and can only be read once. - * @since 5.2 - * @see #getMultipartData() - */ - Flux getParts(); - /** * Return the {@link LocaleContext} using the configured * {@link org.springframework.web.server.i18n.LocaleContextResolver}. diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java index 41e7a2c6ad..87a2715605 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerWebExchangeDecorator.java @@ -20,7 +20,6 @@ import java.time.Instant; import java.util.Map; import java.util.function.Function; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.context.ApplicationContext; @@ -108,11 +107,6 @@ public class ServerWebExchangeDecorator implements ServerWebExchange { return getDelegate().getMultipartData(); } - @Override - public Flux getParts() { - return getDelegate().getParts(); - } - @Override public boolean isNotModified() { return getDelegate().isNotModified(); diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java index cc2c65da11..984615c6d3 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.context.ApplicationContext; @@ -66,7 +65,8 @@ public class DefaultServerWebExchange implements ServerWebExchange { private static final ResolvableType FORM_DATA_TYPE = ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class); - private static final ResolvableType PARTS_DATA_TYPE = ResolvableType.forClass(Part.class); + private static final ResolvableType MULTIPART_DATA_TYPE = ResolvableType.forClassWithGenerics( + MultiValueMap.class, String.class, Part.class); private static final Mono> EMPTY_FORM_DATA = Mono.just(CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap(0))) @@ -91,8 +91,6 @@ public class DefaultServerWebExchange implements ServerWebExchange { private final Mono> multipartDataMono; - private final Flux partFlux; - @Nullable private final ApplicationContext applicationContext; @@ -131,8 +129,7 @@ public class DefaultServerWebExchange implements ServerWebExchange { this.sessionMono = sessionManager.getSession(this).cache(); this.localeContextResolver = localeContextResolver; this.formDataMono = initFormData(request, codecConfigurer, getLogPrefix()); - this.partFlux = initParts(request, codecConfigurer, getLogPrefix()); - this.multipartDataMono = initMultipartData(this.partFlux); + this.multipartDataMono = initMultipartData(request, codecConfigurer, getLogPrefix()); this.applicationContext = applicationContext; } @@ -159,33 +156,27 @@ public class DefaultServerWebExchange implements ServerWebExchange { } @SuppressWarnings("unchecked") - private static Flux initParts(ServerHttpRequest request, ServerCodecConfigurer configurer, String logPrefix) { + private static Mono> initMultipartData(ServerHttpRequest request, + ServerCodecConfigurer configurer, String logPrefix) { + try { MediaType contentType = request.getHeaders().getContentType(); if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) { - return ((HttpMessageReader)configurer.getReaders().stream() - .filter(reader -> reader.canRead(PARTS_DATA_TYPE, MediaType.MULTIPART_FORM_DATA)) + return ((HttpMessageReader>) configurer.getReaders().stream() + .filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA)) .findFirst() .orElseThrow(() -> new IllegalStateException("No multipart HttpMessageReader."))) - .read(PARTS_DATA_TYPE, request, Hints.from(Hints.LOG_PREFIX_HINT, logPrefix)) + .readMono(MULTIPART_DATA_TYPE, request, Hints.from(Hints.LOG_PREFIX_HINT, logPrefix)) + .switchIfEmpty(EMPTY_MULTIPART_DATA) .cache(); } } catch (InvalidMediaTypeException ex) { // Ignore } - return Flux.empty(); + return EMPTY_MULTIPART_DATA; } - private static Mono> initMultipartData(Flux parts) { - return parts.collect( - () -> (MultiValueMap) new LinkedMultiValueMap(), - (map, part) -> map.add(part.name(), part)) - .switchIfEmpty(EMPTY_MULTIPART_DATA) - .cache(); - } - - @Override public ServerHttpRequest getRequest() { @@ -230,11 +221,6 @@ public class DefaultServerWebExchange implements ServerWebExchange { return this.multipartDataMono; } - @Override - public Flux getParts() { - return this.partFlux; - } - @Override public LocaleContext getLocaleContext() { return this.localeContextResolver.resolveLocaleContext(this); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java index dfcf50376e..cdfa46cb32 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java @@ -220,11 +220,6 @@ class DefaultServerRequest implements ServerRequest { return this.exchange.getMultipartData(); } - @Override - public Flux parts() { - return this.exchange.getParts(); - } - private ServerHttpRequest request() { return this.exchange.getRequest(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java index bd7e298bf9..a33ce8b7eb 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequestBuilder.java @@ -290,7 +290,8 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { private static final ResolvableType FORM_DATA_TYPE = ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class); - private static final ResolvableType PARTS_DATA_TYPE = ResolvableType.forClass(Part.class); + private static final ResolvableType MULTIPART_DATA_TYPE = ResolvableType.forClassWithGenerics( + MultiValueMap.class, String.class, Part.class); private static final Mono> EMPTY_FORM_DATA = Mono.just(CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap(0))).cache(); @@ -306,16 +307,13 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { private final Mono> multipartDataMono; - private final Flux parts; - public DelegatingServerWebExchange( ServerHttpRequest request, ServerWebExchange delegate, List> messageReaders) { this.request = request; this.delegate = delegate; this.formDataMono = initFormData(request, messageReaders); - this.parts = initParts(request, messageReaders); - this.multipartDataMono = initMultipartData(this.parts); + this.multipartDataMono = initMultipartData(request, messageReaders); } @SuppressWarnings("unchecked") @@ -341,32 +339,26 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { } @SuppressWarnings("unchecked") - private static Flux initParts(ServerHttpRequest request, List> readers) { + private static Mono> initMultipartData(ServerHttpRequest request, + List> readers) { try { MediaType contentType = request.getHeaders().getContentType(); if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) { - return ((HttpMessageReader)readers.stream() - .filter(reader -> reader.canRead(PARTS_DATA_TYPE, MediaType.MULTIPART_FORM_DATA)) + return ((HttpMessageReader>) readers.stream() + .filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA)) .findFirst() .orElseThrow(() -> new IllegalStateException("No multipart HttpMessageReader."))) - .read(PARTS_DATA_TYPE, request, Hints.none()); + .readMono(MULTIPART_DATA_TYPE, request, Hints.none()) + .switchIfEmpty(EMPTY_MULTIPART_DATA) + .cache(); } } catch (InvalidMediaTypeException ex) { // Ignore } - return Flux.empty(); + return EMPTY_MULTIPART_DATA; } - - private static Mono> initMultipartData(Flux parts) { - return parts.collect( - () -> (MultiValueMap) new LinkedMultiValueMap(), - (map, part) -> map.add(part.name(), part)) - .switchIfEmpty(EMPTY_MULTIPART_DATA) - .cache(); - } - @Override public ServerHttpRequest getRequest() { return this.request; @@ -382,11 +374,6 @@ class DefaultServerRequestBuilder implements ServerRequest.Builder { return this.multipartDataMono; } - @Override - public Flux getParts() { - return this.parts; - } - // Delegating methods @Override diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java index acf120c044..f098c57a6c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java @@ -1025,11 +1025,6 @@ public abstract class RequestPredicates { return this.request.multipartData(); } - @Override - public Flux parts() { - return this.request.parts(); - } - @Override public ServerWebExchange exchange() { return this.request.exchange(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java index 55ca6c69e7..72147d6898 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java @@ -270,23 +270,9 @@ public interface ServerRequest { *

Note: calling this method causes the request body to * be read and parsed in full, and the resulting {@code MultiValueMap} is * cached so that this method is safe to call more than once. - *

Note:the {@linkplain Part#content() contents} of each - * part is not cached, and can only be read once. */ Mono> multipartData(); - /** - * Get the parts of a multipart request if the Content-Type is - * {@code "multipart/form-data"} or an empty flux otherwise. - *

Note: calling this method causes the request body to - * be read and parsed in full and the resulting {@code Flux} is - * cached so that this method is safe to call more than once. - *

Note:the {@linkplain Part#content() contents} of each - * part is not cached, and can only be read once. - * @since 5.2 - */ - Flux parts(); - /** * Get the web exchange that this request is based on. *

Note: Manipulating the exchange directly (instead of using the methods provided on diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java index ffed975f7f..4ae5fea57b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java @@ -208,11 +208,6 @@ public class ServerRequestWrapper implements ServerRequest { return this.delegate.multipartData(); } - @Override - public Flux parts() { - return this.delegate.parts(); - } - @Override public ServerWebExchange exchange() { return this.delegate.exchange(); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java index deeb681a43..d49ffde395 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/MultipartIntegrationTests.java @@ -129,7 +129,8 @@ public class MultipartIntegrationTests extends AbstractRouterFunctionIntegration private static class MultipartHandler { public Mono multipartData(ServerRequest request) { - return request.multipartData() + return request + .body(BodyExtractors.toMultipartData()) .flatMap(map -> { Map parts = map.toSingleValueMap(); try { @@ -145,7 +146,7 @@ public class MultipartIntegrationTests extends AbstractRouterFunctionIntegration } public Mono parts(ServerRequest request) { - return request.parts().collectList() + return request.body(BodyExtractors.toParts()).collectList() .flatMap(parts -> { try { assertThat(parts.size()).isEqualTo(2); @@ -160,7 +161,7 @@ public class MultipartIntegrationTests extends AbstractRouterFunctionIntegration } public Mono transferTo(ServerRequest request) { - return request.parts() + return request.body(BodyExtractors.toParts()) .filter(part -> part instanceof FilePart) .next() .cast(FilePart.class) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java index c066a51a09..9641402558 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java @@ -247,13 +247,6 @@ public class MockServerRequest implements ServerRequest { return (Mono>) this.body; } - @Override - @SuppressWarnings("unchecked") - public Flux parts() { - Assert.state(this.body != null, "No body"); - return (Flux) this.body; - } - @Override public ServerWebExchange exchange() { Assert.state(this.exchange != null, "No exchange");