英文:
How do you use Spring WebClient as a file download passthru
问题
我正在尝试使用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<DataBuffer>
,但仍然收到相同的错误消息。
我正在使用spring-boot-starter-web
和spring-boot-starter-webflux
版本2.2.4.RELEASE。它在一个Tomcat服务器上运行。
我错过了什么吗?
编辑:
我试图将结果以流的方式传输到客户端,而不将整个文件缓冲到内存中。
英文:
I am trying to use WebClient to download a file from a external service and return it to the client. In the Rest Controller, I have the following endpoint:
@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);
}
When I try to hit the endpoint, I get the following error:
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)
I have tried returning Flux<DataBuffer>
instead, but getting the same error message.
I'm using spring-boot-starter-web
and spring-boot-starter-webflux
version 2.2.4.RELEASE. It is running on a tomcat server.
What am I missing?
Edit:
I'm trying to stream the result to the client without buffering the whole file into memory.
答案1
得分: 2
这对我来说是可以的。只需将Flux更改为Mono。似乎没有Flux<byte[]>的转换器。
@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);
}
英文:
This works for me. Just change from Flux to Mono. Seem there is no converter for Flux<byte[]>
@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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论