Spring Integration WebFlux outboundGateway ClientHttpResponse to Mono<Object>

Как мы преобразуем Flux<DataBuffer> из ClientHttpResponse в Mono<SomeDto>. Кроме того, можем ли мы получить доступ к MessageHeaders в bodyExtractor. Пожалуйста, предложите.

.handle(WebFlux.outboundGateway(apiUrl, webClient)
                .httpMethod(POST)
                .mappedRequestHeaders(CONTENT_TYPE)
                .bodyExtractor((clientHttpResponse, context) -> validateAPIResponse(clientHttpResponse)))


private Mono<Object> validateAPIResponse(final ClientHttpResponse clientHttpResponse) {

    var httpStatus = clientHttpResponse.getStatusCode();

    // check for 500
    if (httpStatus.is5xxServerError())
        throw new SomeException(.......);

    var responseMono = new Jackson2JsonDecoder().decodeToMono(clientHttpResponse.getBody(), ResolvableType.forClass(SomDto.class), null,
            null);

    // check for any other than 200
    if (!httpStatus.is2xxSuccessful())
        return responseMono.map(response -> {
            throw new SomeOtherException(response.getSomeField(), httpStatus);
        });
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете просто делегировать BodyExtractors.toFlux(SomDto.class). Я не уверен, что вам действительно нужен кастом BodyExtractor, если просто expectedResponseType(SomDto.class) должно быть достаточно, чтобы вы произвели такой Mono. Не уверен также, что вам нужно самостоятельно обрабатывать эти ошибки: фреймворк делает достойную работу по этому вопросу.

Да, вы не можете получить доступ к MessageHeaders в этом контексте BodyExtractor, так как это не имеет ничего общего с обменом сообщениями.

Вы можете получить доступ к этим заголовкам немного ниже по течению, когда вы уже получили ответ от этого шлюза WebFlux. Если ваш ответ действительно сильно привязан к заголовкам, вам нужно подумать о создании общего ответа (например, Flux<DataBuffer>), а затем соответствующим образом преобразовать его в преобразователь, где вы уже получаете доступ ко всему сообщению запроса и его заголовкам.

См. также это в документах:

Spring Integration предоставляет ClientHttpResponseBodyExtractor в качестве функции идентификации для создания (ниже по течению) всего ClientHttpResponse и любой другой возможной пользовательской логики.

Спасибо за подробное объяснение. Наш вариант использования — знать HttpStatusCode и действовать соответственно (фактически продолжать поток), а не отправлять сообщение errorChannel. С обычным expectedResponseType() любая серия, кроме 2xx, шла на errorChannel, отсюда и необходимость кастомных BodyExtractor

Rayyan 19.01.2023 19:47

Не могли бы вы предложить, позволяет ли фреймворк обрабатывать ответ WebFlux с помощью statusCode, а не через errorChannel?

Rayyan 19.01.2023 20:18

Нет. Вы правы: разумное поведение по умолчанию — продолжить с 2xx и потерпеть неудачу с 5xx или 4xx. Итак, посмотрите, может ли мое другое предложение с этим ClientHttpResponseBodyExtractor помочь вам.

Artem Bilan 19.01.2023 20:44

Пробовал пользовательский BodyExtractor, а также ClientHttpResponseBodyExtractor, в обоих случаях в конце, если это не статус 2xx, он переходит в errorChannel. Пример доступен по адресу github.com/syedyusufh/webflux-inboundgateway-error, вам нужна фиктивная конечная точка, чтобы вернуть 400. Пожалуйста, помогите

Rayyan 20.01.2023 06:20

Здравствуйте @Artem, не могли бы вы попробовать образец, которым поделились, и дать нам несколько предложений, чтобы продолжить поток, не бросая WebFlux ответ на errorChannel

Rayyan 23.01.2023 16:01

В настоящее время WebFluxRequestExecutingMessageHandler выполняет этот жесткий код: .onStatus(HttpStatusCode::isError, ClientResponse::createException). См. его JavaDocs: интересно, ExchangeFilterFunction, введенный в WebClient, предусмотренный для этого WebFluxRequestExecutingMessageHandler, поможет смягчить эту проблему. Например, вы можете преобразовать ClientResponse, чтобы у вас не было плохого кода состояния. Смотрите DefaultClientResponseBuilder.

Artem Bilan 23.01.2023 16:45

Большое спасибо, мутация ClientResponse через ExchangeFilterFunction сделала свое дело вместе с пользовательским заголовком, чтобы узнать оригинал HttpStatus

Rayyan 24.01.2023 03:26

Другие вопросы по теме