问题
I'm looking for a piece of code with Webflux that can handle a json part and a files stream. The request can upload a lot of files so I want to process one file at the time with zero copy by using a Flux (and not a flux on a preloaded Map). I think I tried everything and this is my last implementation that doesn't work well:
This is my unit test:
@Test
@DisplayName("[TU] Http upload series")
public void uploadSeries() {
ArgumentCaptor<Mono<SeriesMetaDTO>> metaMono = ArgumentCaptor.forClass(Mono.class);
ArgumentCaptor<Flux<DataBuffer>> dicomFlux = ArgumentCaptor.forClass(Flux.class);
doReturn(Flux.empty()).when(service).create(any(), any());
webTestClient.post()
.uri(SeriesApiRouter.RESOURCE)
.bodyValue(generateBody())
.exchange()
.expectStatus().is2xxSuccessful()
;
verify(service).create(metaMono.capture(), dicomFlux.capture());
StepVerifier.create(metaMono.getValue().log())
.expectNext(new SeriesMetaDTO(List.of("TITI", "TOTO")))
.verifyComplete();
StepVerifier.create(dicomFlux.getValue().log())
.expectNextCount(3)
.verifyComplete();
}
A controller way approch:
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<ServerResponse> postStreamSeries(
@RequestPart("meta") Mono<SeriesMetaDTO> meta,
@RequestPart("dicoms") Flux<Part> dicoms
) {
var dicomsFlux = dicoms
.map(Part::content)
.flatMap(DataBufferUtils::join)
.log()
;
return ServerResponse.ok().body(BodyInserters.fromPublisher(service.create(meta, dicomsFlux), String.class));
}
A functional way approch:
public Mono<SeriesMetaDTO> extractSerieMeta(MultiValueMap map) {
return (Mono<SeriesMetaDTO>) map.getFirst("meta");
}
public Mono<ServerResponse> postStreamSeries(ServerRequest request) {
var meta = request.multipartData()
.flatMap(this::extractSerieMeta)
.ofType(SeriesMetaDTO.class)
.single();
var files = request.body(BodyExtractors.toParts())
.ofType(FilePart.class)
.map(Part::content)
.flatMap(DataBufferUtils::join);
return ServerResponse.ok().body(BodyInserters.fromPublisher(service.create(meta,files), String.class));
}
Can you see what I missed here? Thanks you.
来源:https://stackoverflow.com/questions/58500409/how-to-upload-mono-of-json-and-flux-of-files-with-webflux