Обработка MessageHandlingException с рекомендациями и продолжение интеграции потоковой пружины dsl - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь подавить исключение MessageHandlingException, сгенерированное из исходящего шлюза http для кодов состояния, отличного от 2XX, и корректно вернуть элемент управления в родительский поток, чтобы сообщение с исходной полезной нагрузкой возвращалось в канал ответа, как и предполагалось, в потоке успеха.

оригинальный код:

 @Bean
  public IntegrationFlow inquiry() {
    return flow -> flow
    .handle(Http
                .outboundGateway("url", restTemplate)
                .mappedRequestHeaders("*")
                .headerMapper(headerMapper)
                .extractPayload(true)
                .httpMethod(HttpMethod.POST)
                .expectedResponseType(expectedResponseType.class)
            )

Я пытался с errorHandler на Http, но он дает дескриптор ответа клиента, и оригинальная полезная нагрузка не является его частью.

Маршрут Tried Expression Advice.

@Bean
  public IntegrationFlow inquiry() {
    return flow -> flow
    .handle(Http
                    .outboundGateway("url", restTemplate)
                    .mappedRequestHeaders("*")
                    .headerMapper(headerMapper)
                    .extractPayload(true)
                    .httpMethod(HttpMethod.POST)
                    .expectedResponseType(expectedResponseType.class)
                , c->c.advice(expresionAdvice())) 

Совет не возвращает элемент управления, если нет канала успеха и неудачи, но намерение вернуть элемент управления родителю.

Вероятно, самый простой способ - обернуть .handle с помощью try.. catch, перехватить исключение MessageHandlingException, передать его в @ExceptionHandler и преобразовать его.

есть ли способ сделать это с помощью advice или errorChannel, попробовав errorChannel на @MessagingGateway, который не вызывается после 404 из http исходящего шлюза.

Приведенный выше код является частью другого потока, и я тестирую этот поток независимо.

может ли быть канал с ошибкой при интеграции потока?

Обновление 1:

смог выяснить, почему errorChannel на @MessagingGateway не вызывается из теста, он вызывается только при вызове всего потока, а не только inquiry() метод, использующий DirectChannel.

Теперь, когда errorChannel работает, установите настраиваемый заголовок, используя состояние полезной нагрузки, которое было до исключения, и получите доступ к нему из заголовка failedMessage.

теперь он работает как положено и никогда не возвращает ошибку в ответ. Чувствую, что это работа вокруг ..

есть ли способ, которым можно лучше справиться в совете?

РЕДАКТИРОВАТЬ 1:

Код не полный, я пытался заставить его работать

@Bean
  public Advice expressionAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setOnSuccessExpressionString("payload");
    advice.setOnFailureExpressionString("payload");
    advice.setTrapException(true);
    return advice;
  }

Так как я не указал поток канала из рекомендации, потоку некуда идти, нужна какая-то вещь, например .defaultOutputToParentFlow(), чтобы он возвращался в родительский поток с Message.

Ответ:

Это сработало, Но единственная проблема в том, что мне все еще нужен пользовательский заголовок, чтобы получить исходную полезную нагрузку, а не запрашивать полезную нагрузку / тело для продолжения процесса.

@Bean
  public Advice expressionAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setOnSuccessExpressionString("payload");
    advice.setOnFailureExpressionString("headers['CUSTOM_KEY']");
    advice.setTrapException(true);
    advice.setReturnFailureExpressionResult(true);
    return advice;
  }

Это то, что я искал. Может быть изменено имя переменной, так как совет вернется к успеху, а не только к ошибкам.

1 Ответ

0 голосов
/ 19 сентября 2018

Вам также необходимо настроить ExpressionEvaluatingRequestHandlerAdvice на true:

/**
 * If true, the result of evaluating the onFailureExpression will
 * be returned as the result of AbstractReplyProducingMessageHandler.handleRequestMessage(Message).
 *
 * @param returnFailureExpressionResult true to return the result of the evaluation.
 */
public void setReturnFailureExpressionResult(boolean returnFailureExpressionResult) {
    this.returnFailureExpressionResult = returnFailureExpressionResult;
}
...