我正在使用 webflux 构建 Java SpringBoot 项目。这是方法:
public Mono<ServerResponse> downloadAttachment(final ServerRequest request) {
String fileName = "prova_B400.png";
final var idPercorso = request.queryParam("idPercorso")
.map(Integer::parseInt).orElse(null);
//mi serve la tripletta
//1 tipo di storage
//2 percorso allegati
//3 nome file
Mono<MapFile>mapFile= silverMountainService(super.parseUserInfo(request).block()).getMapFile(idPercorso);
return Mono.zip(parseUserInfo(request), request.bodyToMono(ObjectNode.class))
.flatMap(t -> {
//var dto = t.getT2();
return silverMountainService(t.getT1()).downloadMappaPercorso(
StorageType.parse(mapFile.block().storageType),
mapFile.block().omniaClass,
fileName
)
.flatMap(fileResult -> ServerResponse.ok()
.headers(h -> h.setContentDisposition(
Optional.ofNullable(fileName)
.filter(StringUtils::isNotBlank)
.map(filename -> ContentDisposition.attachment().filename(filename).build())
.orElseGet(() -> ContentDisposition.inline().build() )
))
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(BodyInserters.fromValue(fileResult.getContent()))
);
})
.onErrorResume(CustomHttpException.class, assEx -> {
log.error("Error({}): {}", assEx.getErrorId(), assEx.getMessage());
return ServerResponse.status(assEx.getHttpStatus()).bodyValue(String.format("ErrorID: %s", assEx.getErrorId()));
})
.onErrorResume(Exception.class, ex -> {
var errId = UUID.randomUUID().toString();
log.error(String.format("Error(%s) %s", errId, ex.getMessage()), ex);
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).bodyValue(String.format("ErrorID: %s", errId));
});
}
通过这种方法,我需要获取包含三个字段的 mapFile 对象以在“silverMountainService.downloadMappaPercorso”中使用。
要编译项目,我必须使用 mapFile.block(),但如果我尝试调用此方法,我会收到以下错误:
lock()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-6
我怎样才能更改我的代码?
您必须检查代码,使用反应式 API 方法并避免使用
block
。一般的想法是,如果您需要使用来自一个发布者的参数,下游与其他发布者一起使用,请创建一个新方法而不是嵌套结构。我还建议检查使用 的逻辑ServerRequest
,每次操作它时,都会执行一个新请求。