11/*
2- * Copyright 2002-2018 the original author or authors.
2+ * Copyright 2002-2019 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2525import java .util .concurrent .ConcurrentHashMap ;
2626import java .util .function .Function ;
2727
28+ import reactor .core .publisher .Flux ;
2829import reactor .core .publisher .Mono ;
2930
3031import org .springframework .context .ApplicationContext ;
@@ -65,8 +66,7 @@ public class DefaultServerWebExchange implements ServerWebExchange {
6566 private static final ResolvableType FORM_DATA_TYPE =
6667 ResolvableType .forClassWithGenerics (MultiValueMap .class , String .class , String .class );
6768
68- private static final ResolvableType MULTIPART_DATA_TYPE = ResolvableType .forClassWithGenerics (
69- MultiValueMap .class , String .class , Part .class );
69+ private static final ResolvableType PARTS_DATA_TYPE = ResolvableType .forClass (Part .class );
7070
7171 private static final Mono <MultiValueMap <String , String >> EMPTY_FORM_DATA =
7272 Mono .just (CollectionUtils .unmodifiableMultiValueMap (new LinkedMultiValueMap <String , String >(0 )))
@@ -91,6 +91,8 @@ public class DefaultServerWebExchange implements ServerWebExchange {
9191
9292 private final Mono <MultiValueMap <String , Part >> multipartDataMono ;
9393
94+ private final Flux <Part > partFlux ;
95+
9496 @ Nullable
9597 private final ApplicationContext applicationContext ;
9698
@@ -129,7 +131,8 @@ public DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse re
129131 this .sessionMono = sessionManager .getSession (this ).cache ();
130132 this .localeContextResolver = localeContextResolver ;
131133 this .formDataMono = initFormData (request , codecConfigurer , getLogPrefix ());
132- this .multipartDataMono = initMultipartData (request , codecConfigurer , getLogPrefix ());
134+ this .partFlux = initParts (request , codecConfigurer , getLogPrefix ());
135+ this .multipartDataMono = initMultipartData (this .partFlux );
133136 this .applicationContext = applicationContext ;
134137 }
135138
@@ -156,28 +159,34 @@ private static Mono<MultiValueMap<String, String>> initFormData(ServerHttpReques
156159 }
157160
158161 @ SuppressWarnings ("unchecked" )
159- private static Mono <MultiValueMap <String , Part >> initMultipartData (ServerHttpRequest request ,
160- ServerCodecConfigurer configurer , String logPrefix ) {
161-
162+ private static Flux <Part > initParts (ServerHttpRequest request , ServerCodecConfigurer configurer , String logPrefix ) {
162163 try {
163164 MediaType contentType = request .getHeaders ().getContentType ();
164165 if (MediaType .MULTIPART_FORM_DATA .isCompatibleWith (contentType )) {
165- return ((HttpMessageReader <MultiValueMap < String , Part >>) configurer .getReaders ().stream ()
166- .filter (reader -> reader .canRead (MULTIPART_DATA_TYPE , MediaType .MULTIPART_FORM_DATA ))
166+ return ((HttpMessageReader <Part >) configurer .getReaders ().stream ()
167+ .filter (reader -> reader .canRead (PARTS_DATA_TYPE , MediaType .MULTIPART_FORM_DATA ))
167168 .findFirst ()
168169 .orElseThrow (() -> new IllegalStateException ("No multipart HttpMessageReader." )))
169- .readMono (MULTIPART_DATA_TYPE , request , Hints .from (Hints .LOG_PREFIX_HINT , logPrefix ))
170- .switchIfEmpty (EMPTY_MULTIPART_DATA )
170+ .read (PARTS_DATA_TYPE , request , Hints .from (Hints .LOG_PREFIX_HINT , logPrefix ))
171171 .cache ();
172172 }
173173 }
174174 catch (InvalidMediaTypeException ex ) {
175175 // Ignore
176176 }
177- return EMPTY_MULTIPART_DATA ;
177+ return Flux .empty ();
178+ }
179+
180+ private static Mono <MultiValueMap <String , Part >> initMultipartData (Flux <Part > parts ) {
181+ return parts .collect (
182+ () -> (MultiValueMap <String , Part >) new LinkedMultiValueMap <String , Part >(),
183+ (map , part ) -> map .add (part .name (), part ))
184+ .switchIfEmpty (EMPTY_MULTIPART_DATA )
185+ .cache ();
178186 }
179187
180188
189+
181190 @ Override
182191 public ServerHttpRequest getRequest () {
183192 return this .request ;
@@ -221,6 +230,11 @@ public Mono<MultiValueMap<String, Part>> getMultipartData() {
221230 return this .multipartDataMono ;
222231 }
223232
233+ @ Override
234+ public Flux <Part > getParts () {
235+ return this .partFlux ;
236+ }
237+
224238 @ Override
225239 public LocaleContext getLocaleContext () {
226240 return this .localeContextResolver .resolveLocaleContext (this );
0 commit comments