Comment télécharger plusieurs fichiers avec Webflux?
J'envoie une demande avec le type de contenu: multipart/form-data
et le corps contient un partie dont la valeur est un ensemble de fichiers.
Pour traiter un seul fichier, je le fais comme suit:
Mono<MultiValueMap<String, Part> body = request.body(toMultipartData());
body.flatMap(map -> FilePart part = (FilePart) map.toSingleValueMap().get("file"));
Mais comment le faire pour plusieurs fichiers?
PS. Existe-t-il un autre moyen de télécharger un ensemble de fichiers dans webflux?
J'ai déjà trouvé quelques solutions . Supposons que nous envoyions une requête http POST avec un paramètre fichiers qui contient nos fichiers.
Les réponses sont arbitraires
RestController avec 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.files.forEach(it -> it.transferTo(Paths.get("/tmp/" + it.filename())));
return Mono.just("OK");
}
class Model {
private List<FilePart> files;
//getters and setters
}
Manière fonctionnelle avec 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);
}
Vous pouvez itérer hashmap avec Flux et renvoyer Flux
Flux.fromIterable(hashMap.entrySet())
.map(o -> hashmap.get(o));
et il sera envoyé comme un tableau avec filepart
la clé est utiliser toParts au lieu de toMultipartData , ce qui est plus simple. Voici l'exemple qui fonctionne avec 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);
}