使用建议处理 MessageHandlingException 并继续流程 spring 集成 dsl

Handling MessageHandlingException with advice and continue the flow spring integration dsl

我正在尝试抑制从 http 出站网关为非 2XX 状态代码生成的 MessageHandlingException,并优雅地 return 将控制权返回给 parent 流,以便在成功流程中预期的回复渠道。

原代码:

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

我尝试在 Http 上使用 errorHandler,但它提供了客户端响应的句柄,原始有效负载不是其中的一部分。

也尝试了表达建议路线。

@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())) 

如果没有成功和失败通道,建议不是return返回控制权,而是return返回控制权给parent。

可能最简单的方法是用 try.. catch 包装 .handle 并捕获 MessageHandlingException 并将其传播到 @ExceptionHandler 并转换它。

有没有办法通过建议或 errorChannel 来完成,在 @MessagingGateway 上尝试了 errorChannel 它在来自 http 出站网关的 404 之后没有被调用。

以上代码是另一个流程的一部分,正在独立测试此流程。

integrationFlow 可以有错误通道吗?

更新一:

能够弄清楚为什么 @MessagingGateway 上的 errorChannel 没有从测试中调用,它仅在调用完整流程时被调用,而不是仅使用 DirectChannel 的 inquiry() 方法。

现在 errorChannel 正在工作,使用异常之前的负载状态设置自定义 header 并从 failedMessage Headers.

返回它

它现在按预期工作并且从不向响应返回错误。感觉这是一个变通办法..

有没有办法在建议中更好地处理这个问题?

编辑 1:

代码不完整,我正在尝试让它工作

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

因为我没有从建议中指定通道流,流无处可去,需要像 .defaultOutputToParentFlow() 这样的东西,以便它返回到 parent 流与 Message.

答案:

成功了, 但唯一的问题是,我仍然需要自定义 header 来获取原始有效负载,而不是请求失败 payload/body 才能让进程继续。

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

这就是我要找的。可能会更改变量名称,因为建议将 return 成功,而不仅仅是失败案例。

您还需要在 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;
}