Я новичок в Spring Reactive framework и пытаюсь преобразовать код Springboot 1.5.x в Springboot 2.0. Мне нужно вернуть заголовок ответа после некоторой фильтрации, кода тела и состояния из Spring 5 WebClient ClientResponse. Я не хочу использовать метод block (), поскольку он преобразует его в вызов синхронизации. Я могу довольно легко получить responsebody с помощью bodyToMono. Кроме того, я получаю код состояния, заголовки и текст, если я просто возвращаю ClientResponse, но мне нужно обработать ответ на основе параметров statusCode и заголовка. Я пробовал подписаться, FlatMap и т. д., Но ничего не работает.
Например. - Код ниже вернет тело ответа
Mono<String> responseBody = response.flatMap(resp -> resp.bodyToMono(String.class));
Но подобная парадигма не работает для получения заголовков statusCode и Response. Может ли кто-нибудь помочь мне в извлечении параметров statusCode и заголовка с использованием реактивной среды Spring 5.




Вы можете использовать функцию обмена веб-клиента, например.
Mono<String> reponse = webclient.get()
.uri("https://stackoverflow.com")
.exchange()
.doOnSuccess(clientResponse -> System.out.println("clientResponse.headers() = " + clientResponse.headers()))
.doOnSuccess(clientResponse -> System.out.println("clientResponse.statusCode() = " + clientResponse.statusCode()))
.flatMap(clientResponse -> clientResponse.bodyToMono(String.class));
затем вы можете преобразовать bodyToMono и т. д.
Это должно быть отмечено как принятый ответ! У меня сработало, спасибо!
@ C96 это асинхронные вызовы, поэтому вы не можете возвращать значения в традиционном смысле. Вы можете вернуть только Mono и Flux. Выполните обработку внутри метода doOnSuccess.
@thisishantzz, не могли бы вы привести мне пример?
Мне нужно было проверить детали ответа (заголовки, статус и т. д.) И тело.
Единственный способ сделать это - использовать .exchange() с двумя subscribe() в следующем примере:
Mono<ClientResponse> clientResponse = WebClient.builder().build()
.get().uri("https://stackoverflow.com")
.exchange();
clientResponse.subscribe((response) -> {
// here you can access headers and status code
Headers headers = response.headers();
HttpStatus stausCode = response.statusCode();
Mono<String> bodyToMono = response.bodyToMono(String.class);
// the second subscribe to access the body
bodyToMono.subscribe((body) -> {
// here you can access the body
System.out.println("body:" + body);
// and you can also access headers and status code if you need
System.out.println("headers:" + headers.asHttpHeaders());
System.out.println("stausCode:" + stausCode);
}, (ex) -> {
// handle error
});
}, (ex) -> {
// handle network error
});
Я надеюсь, что это помогает. Если кто-то знает, как это сделать лучше, сообщите нам об этом.
Как я могу прочитать код состояния внутри этого метода subscribe () -> {}? Мол, если мне нужно передать код состояния другому методу
Вы можете настроить spring boot> = 2.1.0 для регистрации запросов и ответов, если вы используете WebClient:
spring.http.log-request-details: true
logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE
Как описано в документации по загрузке спринта, если вы хотите, чтобы заголовки тоже регистрировались, вы должны добавить
Consumer<ClientCodecConfigurer> consumer = configurer ->
configurer.defaultCodecs().enableLoggingRequestDetails(true);
WebClient webClient = WebClient.builder()
.exchangeStrategies(ExchangeStrategies.builder().codecs(consumer).build())
.build();
Но имейте в виду, что это может регистрировать чувствительную информацию.
Спрашивающий говорит ... Мне нужно обработать ответ на основе параметров statusCode и заголовка.. Но код, который вы предоставили, предназначен для конфигурации журнала, что означает, что он бесполезен в контексте вопроса. Следовательно -1.
@AdinduStevens, мне жаль, что я не понял этого из вопроса. Я оставлю здесь ответ на тот случай, если кто-то приземлится здесь и захочет зарегистрировать только кодировщик состояния и параметры заголовка.
Для кода состояния вы можете попробовать следующее:
Mono<HttpStatus> status = webClient.get()
.uri("/example")
.exchange()
.map(response -> response.statusCode());
Для заголовков:
Mono<HttpHeaders> result = webClient.get()
.uri("/example")
.exchange()
.map(response -> response.headers().asHttpHeaders());
Как мне распечатать значение "статуса"? Как просто "200", а не весь объект Mono <>
После Spring Boot 2.4.x / Spring 5.3 метод WebClient exchange устарел в пользу retrieve, поэтому вам нужно получить заголовки и статус ответа с помощью ResponseEntity, как в следующем примере:
webClient
.method(HttpMethod.POST)
.uri(uriBuilder -> uriBuilder.path(loginUrl).build())
.bodyValue(new LoginBO(user, passwd))
.retrieve()
.toEntity(LoginResponse.class)
.filter(
entity ->
entity.getStatusCode().is2xxSuccessful()
&& entity.getBody() != null
&& entity.getBody().isLogin())
.flatMap(entity -> Mono.justOrEmpty(entity.getHeaders().getFirst(tokenHeader)));
httpClient
.get()
.uri(url)
.retrieve()
.toBodilessEntity()
.map(reponse -> Tuple2(reponse.statusCode, reponse.headers))
Но это просто печатает код HttpStatus. Что, если мне нужно вернуть его значение? Возможно ли это?