代码之家  ›  专栏  ›  技术社区  ›  Vladlen Gladis

如何使用WebFlux上传多个文件?

  •  10
  • Vladlen Gladis  · 技术社区  · 7 年前

    如何使用WebFlux上传多个文件?

    我发送内容类型为: multipart/form-data 身体里有一个 部分 哪个值是一组文件。

    要处理单个文件,我按如下方式进行:

    Mono<MultiValueMap<String, Part> body = request.body(toMultipartData());
    body.flatMap(map -> FilePart part = (FilePart) map.toSingleValueMap().get("file"));
    

    但是如何处理多个文件呢?

    还有其他方法可以在WebFlux中上传一组文件吗?

    4 回复  |  直到 7 年前
        1
  •  4
  •   Ricard Kollcaku    7 年前

    可以使用flux和return flux迭代hashmap

    Flux.fromIterable(hashMap.entrySet())
                .map(o -> hashmap.get(o));
    

    它将作为带有文件部分的数组发送

        2
  •  0
  •   nekperu15739    7 年前

    关键是使用 拓普艺术 而不是 多节数据 更简单。下面是与 路由器功能 .

    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);
    }
    
        3
  •  0
  •   Vladlen Gladis    7 年前

    我已经找到了一些解决办法。 假设我们发送一个带有参数的HTTP POST请求 文件夹 其中包含我们的文件。

    注:回答是任意的

    1. 带请求部分的RestController

      @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"));
      }
      
    2. 带modelattribute的restcontroller

      @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
      }
      
    3. 带手柄功能的功能方式

      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);
      }
      
        4
  •  -1
  •   vsoni    7 年前

    下面是使用WebFlux上载多个文件的工作代码。

    @RequestMapping(value = "upload", method = RequestMethod.POST)
        Mono<Object> upload(@RequestBody Flux<Part> parts) {
    
            return parts.log().collectList().map(mparts -> {
                return mparts.stream().map(mmp -> {
                    if (mmp instanceof FilePart) {
                        FilePart fp = (FilePart) mmp;
                        fp.transferTo(new File("c:/hello/"+fp.filename()));
                    } else {
                        // process the other non file parts
                    }
                    return mmp instanceof FilePart ? mmp.name() + ":" + ((FilePart) mmp).filename() : mmp.name();
                }).collect(Collectors.joining(",", "[", "]"));
            });
    
        };