我是WebClient
和反应式编程的新手。我想从请求中获取响应主体。如果发生错误,则必须记录http代码,标头和正文,但仍应返回正文。
经过大量的挖掘和谷歌搜索,我找到了两种解决方案。但是,两者对我来说都显得复杂。有没有更简单的解决方案?
与Mono
在一起,我找到了以下解决方案:
public Mono<String> log(ProtocolLine protocolLine) {
return webClient.post()
.uri("/log")
.body(BodyInserters.fromObject(protocolLine))
.exchange()
.flatMap(clientResponse -> {
Mono<String> stringMono = clientResponse.bodyToMono(String.class);
CompletableFuture<String> stringCompleteFuture = new CompletableFuture<String>();
Mono<String> bodyCompletedMono = Mono.fromFuture(stringCompleteFuture);
if (clientResponse.statusCode().isError()) {
stringMono.subscribe(bodyString -> {
LOGGER.error("HttpStatusCode = {}", clientResponse.statusCode());
LOGGER.error("HttpHeaders = {}", clientResponse.headers().asHttpHeaders());
LOGGER.error("ResponseBody = {}", bodyString);
stringCompleteFuture.complete(bodyString);
});
}
return bodyCompletedMono;
});
}
基于Flux
,它需要较少的代码。但是我想,如果我知道只有一个结果,我就不应该使用Flux。
public Flux<String> log(ProtocolLine protocolLine) {
return webClient.post()
.uri("/log")
.body(BodyInserters.fromObject(protocolLine))
.exchange()
.flux()
.flatMap(clientResponse -> {
Flux<String> stringFlux = clientResponse.bodyToFlux(String.class).share();
if (clientResponse.statusCode().isError()) {
stringFlux.subscribe(bodyString -> {
LOGGER.error("HttpStatusCode = {}", clientResponse.statusCode());
LOGGER.error("HttpHeaders = {}", clientResponse.headers().asHttpHeaders());
LOGGER.error("ResponseBody = {}", bodyString);
});
}
return stringFlux;
});
}
答案 0 :(得分:1)
public Mono<String> log(ProtocolLine protocolLine) {
return webClient.post()
.uri("/log")
.body(BodyInserters.fromObject(protocolLine))
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(String.class)
.doOnSuccess(body -> {
if (clientResponse.statusCode().isError()) {
log.error("HttpStatusCode = {}", clientResponse.statusCode());
log.error("HttpHeaders = {}", clientResponse.headers().asHttpHeaders());
log.error("ResponseBody = {}", body);
}
}));
}
在这里您可以看到思维方式。我们总是拿clientResponse
并将其主体映射到字符串。然后,doOnSuccess
Mono
被订户(我们的主叫客户端)消耗时doOnSuccess
,并检查状态码是否有错误,如果是这种情况,我们会记录。
Mono
方法返回void,因此它不会“消耗”单声道或其他任何东西,它只会在此Flux
说它“本身具有某种东西”,“完成”时触发一些东西。如此一窥。
这可以与NaN
相同地使用。