How to upload multiple files using Webflux?
Solution 1
I already found some solutions. Let's suppose that we send an http POST request with an parameter files which contains our files.
Note responses are arbitrary
-
RestController with RequestPart
@PostMapping("/upload") public Mono<String> process(@RequestPart("files") Flux<FilePart> filePartFlux) { return filePartFlux.flatMap(it -> it.transferTo(Paths.get("/tmp/" + it.filename()))) .then(Mono.just("OK")); }
-
RestController with ModelAttribute
@PostMapping("/upload-model") public Mono<String> processModel(@ModelAttribute Model model) { model.getFiles().forEach(it -> it.transferTo(Paths.get("/tmp/" + it.filename()))); return Mono.just("OK"); } class Model { private List<FilePart> files; //getters and setters }
-
Functional way with HandlerFunction
public Mono<ServerResponse> upload(ServerRequest request) { Mono<String> then = request.multipartData().map(it -> it.get("files")) .flatMapMany(Flux::fromIterable) .cast(FilePart.class) .flatMap(it -> it.transferTo(Paths.get("/tmp/" + it.filename()))) .then(Mono.just("OK")); return ServerResponse.ok().body(then, String.class); }
Solution 2
You can iterate hashmap with Flux and return Flux
Flux.fromIterable(hashMap.entrySet())
.map(o -> hashmap.get(o));
and it will be send as an array with filepart
Solution 3
the key is use toParts instead of toMultipartData, which is more simpler. Here is the example that works with RouterFunctions.
private Mono<ServerResponse> working2(final ServerRequest request) {
final Flux<Void> voidFlux = request.body(BodyExtractors.toParts())
.cast(FilePart.class)
.flatMap(filePart -> {
final String extension = FilenameUtils.getExtension(filePart.filename());
final String baseName = FilenameUtils.getBaseName(filePart.filename());
final String format = LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE);
final Path path = Path.of("/tmp", String.format("%s-%s.%s", baseName, format, extension));
return filePart.transferTo(path);
});
return ServerResponse
.ok()
.contentType(APPLICATION_JSON_UTF8)
.body(voidFlux, Void.class);
}
Related videos on Youtube
Vladlen Gladis
Software developer at Esempla Systems. Interested in Java Kotlin Angular Spring Boot RESTful Web Services Google(FCM, Static Map, Geocoding etc.) JSP, Thymeleaf Amazon Web Services(S3, SQS, EC2, RDS, Elastic Beanstalk) DevOps(Terraform, Jenkins) Developing plugins for VMware vRO & integration with vRA, Symantic Netbackup, Symantic ObsCenter
Updated on September 16, 2022Comments
-
Vladlen Gladis over 1 year
How to upload multiple files using Webflux?
I send request with content type:
multipart/form-data
and body contains one part which value is a set of files.To process single file I do it as follow:
Mono<MultiValueMap<String, Part> body = request.body(toMultipartData()); body.flatMap(map -> FilePart part = (FilePart) map.toSingleValueMap().get("file"));
But how to done it for multiple files?
PS. Is there another way to upload a set of files in webflux ?
-
Saveriu CIANELLI over 4 yearsHi! This code seems to work for an array of files sent by the client. How can we do with a client that sent a flux of files? Thanks!
-
deHaar over 4 yearsPost an explanation in English, please…