Skip to content

Align multipart codecs on client and server #29630

@CoderYellow

Description

@CoderYellow

According to this check, the response type for controller method should be Mono<MultiValueMap>, but when I use this:

 @GetMapping("multi-part-map", produces = [MULTIPART_FORM_DATA_VALUE]) fun multipartMap(): Mono<MultiValueMap<String, HttpEntity<*>>> { val builder = MultipartBodyBuilder() builder.part("fieldPart", "fieldValue") builder.part("filePart1", FileSystemResource("...logo.png")) builder.part("jsonPart", Person("Jason")) builder.part( "myPart", DefaultFormFieldPart(HttpHeaders(), "myPartName", "myPartData") ) // Part from a server request val parts: MultiValueMap<String, HttpEntity<*>> = builder.build() return Mono.just(parts) }

I got this error:

java.lang.ClassCastException: class org.springframework.util.LinkedMultiValueMap cannot be cast to class org.springframework.http.codec.multipart.Part (org.springframework.util.LinkedMultiValueMap and org.springframework.http.codec.multipart.Part are in unnamed module of loader 'app') at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152) ~[reactor-core-3.5.0.jar:3.5.0]

Because here expects Flux<Part> response type, so I have to implement something like this:

class DefaultFormFieldPart( private val headers: HttpHeaders, private val name: String, private val value: String ) : Part, MultiValueMapAdapter<String, String>(emptyMap()) { override fun content(): Flux<DataBuffer> { return Flux.defer { val bytes = this.value.toByteArray(UTF_8) Flux.just( DefaultDataBufferFactory.sharedInstance.wrap( bytes ) ) } } override fun name(): String { return name } override fun headers(): HttpHeaders { return headers } }
 @GetMapping("multi-part", produces = [MULTIPART_FORM_DATA_VALUE]) fun multipart(): Flux<DefaultFormFieldPart> { return Flux.fromIterable(listOf("part1", "part2")) .map { it -> DefaultFormFieldPart(HttpHeaders().also { it.contentType = MediaType.TEXT_PLAIN }, it, "$it data") } } 

It makes no sense to check against MultiValueMap if the encoder only treats it as Flux<Part>

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions