Spring WebClient 支持 Multiparts/related 吗?

Posted

技术标签:

【中文标题】Spring WebClient 支持 Multiparts/related 吗?【英文标题】:does Spring WebClient support Multiparts/related? 【发布时间】:2022-01-15 22:58:23 【问题描述】:

我正在尝试创建 webcleint 以发送多部分/相关类型的内容,但 spring 不断更改内容类型。我创建了一个项目来接收我的请求并检查从 Web 客户端生成的接收到的请求和标头,但是,请求已成功生成,我发现另一个标头(如接受)的正确值作为多部分/相关接收。但是 spring 不断将内容类型从 multipart/related 更改为 multipart/formData。

 webClient.post()
          .uri(endpoint)
          .accept(MediaType.MULTIPART_RELATED)
          .contentType(MediaType.MULTIPART_RELATED)
          .body(BodyInserters.fromMultipartData(createMultiparts()))
          .retrieve()
          .bodyToMono(String.class)
          .subscribe();

createmultiparts 方法:

        public MultiValueMap<String, HttpEntity<?>> createMultiparts() throws IOException 

        File attachment = new File("src/main/resources/attachment.xml");
        File request = new File("src/main/resources/request.xml");
        MultipartBodyBuilder builder = new MultipartBodyBuilder();
        builder.part("body", new String(Files.readAllBytes(request.toPath())))
                .header("Content-Type", "Multipart/related; charset=UTF-8; type=\"text/xml\"")
                .header("Content-Disposition", "");
        builder.part("file", new String(Files.readAllBytes(attachment.toPath())))
                .header("Content-Disposition",
                        "attachment; name=\"811_Bill_Attachment.xml\"; filename=\"811_Bill_Attachment.xml\"")
                .header("Content-ID", "1068118164010");
        return builder.build();
    

有没有什么方法可以在发送请求之前拦截请求以更改内容类型或解决此问题?

以下是接收方打印的日志:

        log.info("recieved request ", httpRequest.getContentType());
        log.info("recieved header ", httpRequest.getHeader("Content-Type"));
        log.info("recieved accept ", httpRequest.getHeader("accept"));
        log.info("recieved body ", new String(httpRequest.getCachedBody()));

logs : recieved request multipart/form-data;boundary=CRsAqXiWZRxzTBwyr4yd7mu5JQhla_
2021-12-11 21:08:09.705  INFO 23592 --- [nio-8081-exec-1] c.e.demo.controller.ServerController     : recieved header multipart/form-data;boundary=CRsAqXiWZRxzTBwyr4yd7mu5JQhla_
2021-12-11 21:08:09.705  INFO 23592 --- [nio-8081-exec-1] c.e.demo.controller.ServerController     : recieved accept multipart/related

【问题讨论】:

是的,他们支持它,但你不能使用fromMultipartData,因为你发送的不是form-data 你试过docs.spring.io/spring-framework/docs/current/javadoc-api/org/… 我已经在使用它来创建多部分我在问题中添加了代码,是否有另一种方法可以在不使用 fromMultipartData 的情况下将多部分传递给正文? 【参考方案1】:

我找到了不使用 body inserters 的解决方案。并将我的多部分添加到 bodyValue 而不是 webclient 的主体。

webClient.post()
                  .uri(endpoint)
                  .accept(MediaType.MULTIPART_RELATED)
                  .contentType(MediaType.MULTIPART_RELATED)
                  .bodyValue(createMultiparts())
                  .retrieve()
                  .bodyToMono(String.class)
                  .subscribe();

由于 bodyValue 内部实现使用 BodyInserter.fromValue(),它不会强制内容类型为 Multipart/form-data,如 fromMultipartData

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于Spring WebClient 支持 Multiparts/related 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Spring WebClient 放置映射:不支持内容类型“application/json”

Spring WebClient 支持 Multiparts/related 吗?

如何在 Spring 响应式 WebClient 中返回 Kotlin Coroutines Flow

是否支持 Spring Boot WebClient OAuth2 client_credentials?

Spring WebClient 作为 RestTemplate 的替代品

WebClient-Reactor风格的异步调用