当文件的内容(Flux;DataBuffer;)包装在另一个对象中时,无法使用WebClient上载文件 [英] Cannot upload a file using WebClient when its content ( Flux<DataBuffer>) is wrapped in another object
本文介绍了当文件的内容(Flux;DataBuffer;)包装在另一个对象中时,无法使用WebClient上载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
Spring Boot:2.5.6,kotlin:1.5.31,kotlinx-coroutines-active:1.5.2
我正在尝试下载一个pdf并立即上传到http://localhost:3000/upload
,如下所示:
Class Mediator(val dataBuffer: Flux<DataBuffer>, val url: String)
runBlocking {
getMediator()
.flatMap { uploadFile(it) }
.subscribe()
}
private fun getMediator(): Mono<Mediator> {
return WebClient.create(
"https://server.com/assets/file.pdf")
.get()
.exchangeToMono { response ->
Mono.just(
Mediator(response.bodyToFlux(DataBuffer::class.java), "http://localhost:3000/upload"))
}
}
private fun uploadFile(mediator: Mediator): Mono<ResponseEntity<Void>> {
return WebClient.create(mediator.url)
.put()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(mediator.dataBuffer)
.retrieve()
.toBodilessEntity()
}
当我运行这段代码时,我可以看到我的服务器收到一个调用并创建了一个空文件(大小为0)。不会引发任何错误。我无法解释为什么这段代码不能将字节传输到我的上载端点。在测试过程中,我意识到问题可能出在getMediator
返回的Mediator
对象中。不知何故,uploadFile
中的body
不像包装的Flux<DataBuffer>
推荐答案
我找到了一种方法。只是回答我自己的问题,以防这可能会对其他人有所帮助。
data class Mediator(val data: Flux<DataBuffer>, val url: String)
data class UploadUrl(val url: String)
runBlocking {
getFileDataBuffer(url)
.flatMap { prepareUpload(it.headers.contentLength, it.body) }
.flatMap { uploadFile(it.url, it.dataBuffer!!)}
}.subscribe()
private fun getFileDataBuffer(url:String): Mono<ResponseEntity<Flux<DataBuffer>>> {
return WebClient.create(url).get().retrieve().toEntityFlux()
}
private fun prepareUpload(length: Long, data: Flux<DataBuffer>?): Mono<Mediator> {
return WebClient.create("http://localhost:3000/prepare")
.post()
.contentType(MediaType.APPLICATION_JSON)
.bodyValue("""{"size":${length}}""")
.exchangeToMono { res ->
res.bodyToMono(String::class.java).map { parseJson<UploadUrl>(it) }.map {
Mediator(data, it.url)
}
}
}
private fun uploadFile(url: String, data: Flux<DataBuffer>): Mono<ResponseEntity<Void>> {
return WebClient.create(url)
.put()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(data)
.retrieve()
.toBodilessEntity()
}
这篇关于当文件的内容(Flux;DataBuffer;)包装在另一个对象中时,无法使用WebClient上载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文