I am developing an API REST using Spring WebFlux, but I have problems when uploading files. They are stored but I don't get the expected return value.
This is what I do:
- Receive a Flux<Part>
- Cast Part to FilePart.
- Save parts with transferTo() (this return a Mono<Void>)
- Map the Mono<Void> to Mono<String>, using file name.
- Return Flux<String> to client.
I expect file name to be returned, but client gets an empty string.
Controller code
@PostMapping(value = "/muscles/{id}/image")
public Flux<String> updateImage(@PathVariable("id") String id, @RequestBody Flux<Part> file) {
log.info("REST request to update image to Muscle");
return storageService.saveFiles(file);
}
StorageService
public Flux<String> saveFiles(Flux<Part> parts) {
log.info("StorageService.saveFiles({})", parts);
return
parts
.filter(p -> p instanceof FilePart)
.cast(FilePart.class)
.flatMap(file -> saveFile(file));
}
private Mono<String> saveFile(FilePart filePart) {
log.info("StorageService.saveFile({})", filePart);
String filename = DigestUtils.sha256Hex(filePart.filename() + new Date());
Path target = rootLocation.resolve(filename);
try {
Files.deleteIfExists(target);
File file = Files.createFile(target).toFile();
return filePart.transferTo(file)
.map(r -> filename);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
.filter(p -> p instanceof FilePart)
you could also use.filter(FilePart.class::isInstance)
- Linolog
operators in your pipeline and share the logs here? Maybe one after thecast
operator to know how many parts you're getting, then another one after theflatMap
to know how many files were transferred. - Brian Clozel