我正在使用Kotlin中的一个小型Spring WebFlux应用程序进行原型设计。此应用程序需要从远程REST端点获取tar存档并将其本地存储在磁盘上。听起来很简单。
我首先创建了一个集成测试,它启动了spring服务器和另一个带有模拟REST端点的WebFlux服务器,该端点为tar存档提供服务。
测试应该如下:
1)app:GET mock-server/archive
2)模拟服务器:状态为200的响应和主体中的tar存档作为类型附件
3)app:阻止直到收到所有字节,然后解压并使用文件
我遇到的问题是,当我尝试将字节收集到应用程序的ByteArray
时,它会永久阻止。
我的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))
}
然后我的应用程序通过以下方式调用它:
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
}
我看到How to best get a byte array from a ClientResponse from Spring WebClient?,这就是我尝试使用ByteArrayResource
的原因。
当我逐步完成所有操作时,我看到serveArchive
似乎正在工作(断言语句说我传递的文件存在并且其中有一些字节)。在retrieveArchive
中我获得了200,并且可以在.headers
中看到所有相应的信息(内容类型,内容长度看起来都很好)。当我到达storeArchive
并尝试使用block
从Mono中检索字节时,它只会永远阻塞。
我完全失去了如何调试这样的东西。
答案 0 :(得分:1)
您只需要从flatMap
返回已转换的正文,以便它从Mono<T>
转换为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()