通过咨询处理MessageHandlingException并继续进行流式弹簧集成dsl

时间:2018-09-18 04:43:45

标签: spring-integration spring-integration-dsl spring-integration-http

我试图抑制从http出站网关为非2XX状态代码生成的MessageHandlingException,并优雅地将控件返回给父流,以便按成功流中的预期在回复通道上返回具有原始有效负载的消息。

原始代码:

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

如果没有成功和失败的渠道,建议不要返回控件,而是将控件返回给父级。

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

有没有一种方法可以通过advice或errorChannel来解决,在@MessagingGateway上尝试了errorChannel,它没有从http出站网关发出404之后被调用。

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

integrationFlow是否存在错误通道?

更新1:

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

现在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 :(得分:0)

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