【发布时间】:2018-12-29 04:47:22
【问题描述】:
我正在尝试使用 Webflux 将生成的文件流式传输到另一个位置,但是,如果文件的生成遇到错误,则 api 返回成功,但在生成文件时使用 DTO 详细说明错误,而不是文件本身。这是使用了一个非常古老且设计不佳的 api,所以请原谅使用 post 和 api 设计。
来自 api 调用 (exchange()) 的响应是 ClientResponse。从这里我可以使用 bodyToMono 转换为 ByteArrayResource,它可以流式传输到文件,或者,如果创建文件时出错,那么我也可以使用 bodyToMono 转换为 DTO。但是,我似乎无法根据 ClientResponse 标头的内容做任何事情。
在运行时我得到一个由
引起的 IllegalStateExceptionblock()/blockFirst()/blockLast()是阻塞的,线程reactor-http-client-epoll-12不支持这个
我认为我的问题是我不能在同一个函数链中调用 block() 两次。
我的代码sn-p是这样的:
webClient.post()
.uri(uriBuilder -> uriBuilder.path("/file/")
.queryParams(params).build())
.exchange()
.doOnSuccess(cr -> {
if (MediaType.APPLICATION_JSON_UTF8.equals(cr.headers().contentType().get())) {
NoPayloadResponseDto dto = cr.bodyToMono(NoPayloadResponseDto.class).block();
createErrorFile(dto);
}
else {
ByteArrayResource bAr = cr.bodyToMono(ByteArrayResource.class).block();
createSpreadsheet(bAr);
}
}
)
.block();
基本上,我想根据标头中定义的 MediaType 以不同方式处理 ClientResponse。
这可能吗?
【问题讨论】:
-
不要阻止,
subscribe。应该没有理由打电话给block。如果您正在使用 WebFlux,那么您这样做是因为您想构建一个反应式管道,如果您正在调用block,那么您并没有这样做。换句话说,如果你调用block,只需使用一个普通的旧RestTemplate- 无论如何,你的代码看起来非常程序化和副作用,所以将它硬塞到 Reactor 不会让它产生神奇的反应。 -
为了澄清我们正在尝试使用 WebClient 将文件从 Web API 流式传输到磁盘。有错误时响应可能是 200 OK application/json,或者没有错误时响应可能是 200 OK Content-Disposition。我们如何在不加载文件的情况下使用 WebClient 来做到这一点完全在记忆中?
标签: java reactive-programming spring-webflux project-reactor