Kotlin Spring WebFlux Webclient以Mono格式接收应用程序/八位字节流文件

Kotlin Spring WebFlux Webclient以Mono格式接收应用程序/八位字节流文件,kotlin,spring-webflux,Kotlin,Spring Webflux,我正在Kotlin中制作一个小型SpringWebFlux应用程序的原型。此应用程序需要从远程REST端点获取tar存档,并将其本地存储在磁盘上。听起来很简单 我首先创建了一个集成测试,启动spring服务器和另一个WebFlux服务器,并使用一个模拟REST端点为tar归档提供服务 测试应该是这样的: 1) 应用程序:获取模拟服务器/存档 2) 模拟服务器:响应状态为200,主体中的tar存档为类型附件 3) 应用程序:阻止,直到收到所有字节,然后卸载并使用文件 我遇到的问题是,当我尝试将字节

我正在Kotlin中制作一个小型SpringWebFlux应用程序的原型。此应用程序需要从远程REST端点获取tar存档,并将其本地存储在磁盘上。听起来很简单

我首先创建了一个集成测试,启动spring服务器和另一个WebFlux服务器,并使用一个模拟REST端点为tar归档提供服务

测试应该是这样的:

1) 应用程序:获取模拟服务器/存档

2) 模拟服务器:响应状态为200,主体中的tar存档为类型附件

3) 应用程序:阻止,直到收到所有字节,然后卸载并使用文件

我遇到的问题是,当我尝试将字节收集到应用程序上的
ByteArray
中时,它会永远阻塞

My
mock server/archive
路由到以下功能:

fun serveArchive(request: ServerRequest): Mono<ServerResponse> {
    val tarFile = FileSystemResource(ARCHIVE_PATH)
    assert(tarFile.exists() && tarFile.isFile && tarFile.contentLength() != 0L)
    return ServerResponse
            .ok()
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .contentLength(tarFile.contentLength())
            .header("Content-Disposition", "attachment; filename=\"$ARCHIVE_FNAME\"")
            .body(fromResource(tarFile))
}
fun-serverchive(请求:ServerRequest):Mono{
val tarFile=FileSystemResource(归档路径)
断言(tarFile.exists()&&tarFile.isFile&&tarFile.contentLength()!=0L)
返回服务器响应
.ok()
.contentType(MediaType.APPLICATION\u八位字节\u流)
.contentLength(tarFile.contentLength())
.header(“内容处置”、“附件;文件名=\”$ARCHIVE\u FNAME\”)
.body(源资源(tarFile))
}
然后,我的应用程序调用以下命令:

private fun retrieveArchive {
    client.get().uri(ARCHIVE_URL).accept(MediaType.APPLICATION_OCTET_STREAM)
            .exchange()
            .flatMap { response ->
                storeArchive(response.bodyToMono())
            }.subscribe()
}

private fun storeArchive(archive: Mono<ByteArrayResource>): Mono<Void> {
    val archiveContentBytes = archive.block() // <- this blocks forever
    val archiveContents = TarArchiveInputStream(archiveContentBytes.inputStream)
    // read archive
}
private fun retrieve{
client.get().uri(ARCHIVE\u URL.accept(MediaType.APPLICATION\u OCTET\u STREAM)
.exchange()
.flatMap{响应->
storeArchive(response.bodyToMono())
}.subscribe()
}
私人娱乐商店档案(档案:Mono):Mono{

val archiveContentBytes=archive.block()//您只需从
flatMap
返回转换后的实体,使其从
Mono
转换为
T

client.get().uri(ARCHIVE_URL).accept(MediaType.APPLICATION_OCTET_STREAM)
            .exchange()
            .flatMap { response ->
                response.bodyToMono(ByteArrayResource::class.java)
            }
            .map { archiveContentBytes ->
                archiveContentBytes.inputStream
            }
            .doOnSuccess { inputStream ->
                //here is you code to do anything with the inputStream
                val archiveContents = TarArchiveInputStream(inputStream)
            }
            .subscribe()

搞定了!谢谢!我最终使用了
…flatMap{response->response.bodytomino()}.map{storeArchive(it)}
并将我的
storeArchive
签名改为使用
ByteArrayResource
。但现在我实际得到了我的字节,并且能够解开存档,等等。非常感谢!