【问题标题】:How do you use Spring WebClient as a file download passthru如何使用 Spring WebClient 作为文件下载 passthru
【发布时间】:2021-02-09 05:24:44
【问题描述】:

我正在尝试使用 WebClient 从外部服务下载文件并将其返回给客户端。在 Rest Controller 中,我有以下端点:

@GetMapping(value = "/attachment/{fileId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Flux<byte[]> get(@PathVariable String fileId) {

    return this.webClient.get()
            .uri(builder ->
                    builder.scheme("https")
                            .host("external-service.com")
                            .path("/{fileId}")
                            .build(fileId)
            ).attributes(clientRegistrationId("credentials"))
            .accept(MediaType.APPLICATION_OCTET_STREAM)
            .retrieve()
            .bodyToFlux(byte[].class);
}

当我尝试到达端点时,我收到以下错误:

Exception Class:class org.springframework.http.converter.HttpMessageNotWritableException
Stack Trace:org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class org.springframework.web.servlet.mvc.method.annotation.ReactiveTypeHandler$CollectedValuesList] with preset Content-Type 'null'
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:317)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181)

我尝试返回 Flux&lt;DataBuffer&gt;,但得到相同的错误消息。

我正在使用 spring-boot-starter-webspring-boot-starter-webflux 版本 2.2.4.RELEASE。它在 tomcat 服务器上运行。

我错过了什么?

编辑: 我正在尝试将结果流式传输到客户端而不将整个文件缓冲到内存中。

【问题讨论】:

标签: java spring-boot spring-webflux spring-webclient


【解决方案1】:

这对我有用。只需从 Flux 更改为 Mono。似乎 Flux

没有转换器
@GetMapping(value = "/attachment/{fileId}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public Mono<byte[]> get(@PathVariable String fileId) {

    return this.webClient.get()
            .uri(builder ->
                    builder.scheme("https")
                            .host("external-service.com")
                            .path("/{fileId}")
                            .build(fileId)
            ).attributes(clientRegistrationId("credentials"))
            .accept(MediaType.APPLICATION_OCTET_STREAM)
            .retrieve()
            .bodyToMono(byte[].class);
}

【讨论】:

  • 当我下载小文件时这对我有用,但在大文件上会出错。有没有办法将结果流式传输到客户端,以便整个文件不存储在内存中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2014-06-20
  • 2010-11-02
  • 1970-01-01
相关资源
最近更新 更多