gpt4 book ai didi

spring-boot - 在错误情况下从 WebClient 获取响应主体的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-05 03:59:56 25 4
gpt4 key购买 nike

我是 WebClient 的新手和响应式(Reactive)编程。我想从请求中获取响应正文。如果出现错误,则必须记录 http 代码、 header 和正文,但仍应返回正文。

经过大量挖掘和谷歌搜索后,我找到了两个解决方案。但对我来说,两者看起来都很复杂。有更简单的解决方案吗?

留在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;
});
}

最佳答案

这两种解决方案都是丑陋且错误的。你几乎不应该在 react 管道的中间订阅。订阅者通常是调用客户端,而不是您自己的应用程序。

    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 并将其主体映射到一个字符串。然后,当订阅者(我们的调用客户端)使用此 Mono 时,我们将 doOnSuccess 并检查状态代码是否有错误,如果是这种情况,我们会记录。

doOnSuccess 方法返回 void,因此它不会“消耗”mono 或任何东西,它只是在这个 Mono 说它“本身有东西”时触发一些东西,当它“完成”时,可以这么说。

这可以以相同的方式与 Flux 一起使用。

关于spring-boot - 在错误情况下从 WebClient 获取响应主体的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56792727/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com