spring-webflux - Spring WebFlux - 通过 webClient 转发 FilePart

标签 spring-webflux multipartform-data spring-webclient

我经历过类似的票证(即 How to stream file from Multipart/form-data in Spring WebFlux ),但显然我的情况略有不同。

高级示例(无错误处理/无“空”检查):

Controller :

@ResponseStatus(code = HttpStatus.CREATED)
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<String> create(
        @RequestPart(value = "images", required = false) final Flux<FilePart> images
    ) {
        ...service-call...
    }

服务:

    public Mono<String> create(
        final Flux<FilePart> images
    ) {
        MultipartBodyBuilder builder = new MultipartBodyBuilder();

        return images
            .filter(part -> Objects.nonNull(part.headers().getContentType()))
            .filter(part ->
                part.headers().getContentType().includes(MediaType.IMAGE_JPEG)
                    || part.headers().getContentType().includes(MediaType.IMAGE_PNG)
            )
            .doOnNext(
                part -> builder
                        .asyncPart("images", part.content(), DataBuffer.class)
                        .filename(part.filename())
            )
            .then(webClient.post()
                .uri(URI_RESOURCE)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(builder.build()))
                .retrieve()
                .bodyToMono(String.class)
            );
    }

问题是,客户端没有收到实际的“图像”:(我添加了一些doOnNext来记录文件被添加到构建器的事实,所以我知道它们是。

我认为这是因为 .asyncPart("images", part.content(), DataBuffer.class)但不确定如何避免/绕过这个内部发布商?

请注意, Controller 期望 Flux基于我看到的所有建议;但是切换到普通 List<FilePart> ,解决了问题,虽然我认为在 WebFlux 中假设“阻止”请求是一种反模式,对吗?

最佳答案

问题是您的 then(webClient...) block 已被调用,并且 MultipartBodyBuilder.build() 在请求开始时执行。您可以使用 Mono.defer 包裹 then 部分。

               ...
               .then(Mono.defer(() -> {
                    return webClient.post()
                            .uri(URI_RESOURCE)
                            .contentType(MediaType.MULTIPART_FORM_DATA)
                            .body(BodyInserters.fromMultipartData(builder.build()))
                            .retrieve()
                            .bodyToMono(String.class);
                }));

关于spring-webflux - Spring WebFlux - 通过 webClient 转发 FilePart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74811994/

相关文章:

ajax - 使用 Nginx Lua POST 请求表单数据操作

java - 使用Spring WebClient在java中上传文件

java - WebClient 从订阅返回值

java - 身份验证期间抛出并处理自定义异常 Spring Security + WebFlux

ajax - jQuery AJAX 'multipart/form-data' 未发送数据?

java - 有没有从 HttpServletRequest 读取表单数据的方法?

spring-boot - Spring webclient - 每次重试后增加超时持续时间

Java Web Flux : How to fetch body from ServerHttpResponse?

file - spring webflux Flux<DataBuffer> 转换为 InputStream

使用 ssl 的 Spring 5 WebClient