оба решения безобразны и ошибочны. Вы почти никогда не должны подписываться в середине реактивного конвейера. Абонентом обычно является вызывающий клиент, а не ваше собственное приложение.
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
возвращает void, поэтому он не «потребляет» моно или что-то еще, он просто запускает что-то, когда этот Mono
говорит, что «что-то есть в себе», когда он «готов», так сказать.
Это можно использовать с Flux
таким же образом.