【问题标题】:Spring-integration ExpressionEvaluatingRequestHandlerAdvice unable to evaluate the failureExpressionSpring-integration ExpressionEvaluatingRequestHandlerAdvice 无法评估 failureExpression
【发布时间】:2021-01-22 09:36:59
【问题描述】:

根据我昨天提出的问题,我发现 ExpressionEvaluatingRequestHandlerAdvice 存在一些问题,因为它没有按我的预期工作。

我尝试了doc example,我的期望是得到两个AdviceMessage:一个说“好是成功的”,另一个说“坏是坏的,有理由......”但是当我运行代码时,我得到了一个 AdviceMessage 和一个 ErrorMessage。

AdviceMessage [payload=good was successful, headers={id=2eb612ea-d3cd-f853-3295-236505a130f3, timestamp=1611307975199}, inputMessage=GenericMessage [payload=good, headers={id=725e89ea-be09-7534-1b29-5c7412a99a79, timestamp=1611307975196}]]
ErrorMessage [payload=org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice$MessageHandlingExpressionEvaluatingAdviceException: Handler Failed; nested exception is java.lang.IllegalStateException: Could not invoke the method 'public java.lang.Object com.example.demo.EerhaApplication$$Lambda$299/0x00000008401d7040.handle(java.lang.Object,org.springframework.messaging.MessageHeaders)', failedMessage=GenericMessage [payload=bad, headers={id=7639425f-7676-d521-5994-4c74e5b09f4a, timestamp=1611307975200}], headers={id=aaa07286-4bc3-71e5-09fb-6b55a46e0ecf, timestamp=1611307975201}]

显然,总是抛出异常,评估 failureExpression 永远不会得到所需的结果。

我使用的是 Spring Boot 2.4.2,但我也尝试过使用旧版本,但始终具有相同的行为。

我做错了什么?

【问题讨论】:

    标签: spring spring-boot spring-integration


    【解决方案1】:

    我们需要查看此 ExpressionEvaluatingRequestHandlerAdvice 的代码,但无论如何,只有在成功评估 onSuccessExpression 的情况下才会发送 AdviceMessage:

    if (evalResult != null && this.successChannel != null) {
        AdviceMessage<?> resultMessage = new AdviceMessage<>(evalResult, message);
        this.messagingTemplate.send(this.successChannel, resultMessage);
    }
    

    当你MessageHandler失败时(即使onSuccessExpression失败了),我们去这个分支:

    catch (RuntimeException e) {
            Exception actualException = unwrapExceptionIfNecessary(e);
            if (this.onFailureExpression != null) {
                Object evalResult = evaluateFailureExpression(message, actualException);
                if (this.returnFailureExpressionResult) {
                    return evalResult;
                }
            }
    

    然后我们发送ErrorMessage:

     if (evalResult != null && this.failureChannel != null) {
            MessagingException messagingException =
                    new MessageHandlingExpressionEvaluatingAdviceException(message, "Handler Failed",
                            unwrapThrowableIfNecessary(exception), evalResult);
            ErrorMessage errorMessage = new ErrorMessage(messagingException);
            this.messagingTemplate.send(this.failureChannel, errorMessage);
        }
    

    所以,你展示的实际上是一种预期的行为。

    因此需要查看您的配置并了解您在这两种情况下的期望。

    【讨论】:

    • 谢谢Artem,代码是我在文档中找到的示例:docs.spring.io/spring-integration/reference/html/…。我希望收到一条消息说“有效负载由于原因而不好......”而似乎从未评估过 onErrorExpression (或者它总是失败)
    • 嗯,"payload was bad for reason..." 是MessageHandlingExpressionEvaluatingAdviceException 的一部分,就像我们使用System.out::println 时一样不可见,您的错误流必须采用@987654336 的evaluationResult 属性@ 要清楚。
    • 知道了,谢谢!有点复杂,但我得到了打印的表达式: System.out.println(((ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException)m.getPayload()).getEvaluationResult());
    • 是的,虽然"payload.evaluationResult" :wink:
    • 我想是时候考虑一​​下了:stackoverflow.com/help/someone-answers
    【解决方案2】:

    为了得到字符串“bad was bad, with reason...”打印,这是我的解决方案:

    @Bean
    public IntegrationFlow failure() {
      return f -> f.handle(m -> {
        System.out.println(((ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException)m.getPayload()).getEvaluationResult());
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 2016-01-26
      • 2021-08-27
      • 2017-04-26
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      相关资源
      最近更新 更多