【问题标题】:Spring Integration Gateway exiting "due to an exception" and not receiving reply after error is handledSpring Integration Gateway 退出“由于异常”并且在处理错误后未收到回复
【发布时间】:2016-02-22 02:07:27
【问题描述】:

嘿,我正在将消息发送到 http 端点,因为我必须在选择性失败时触发错误流,所以我通过网关发送消息,然后最终通过 http 出站网关路由它。

@MessagingGateway(errorChannel="invocationFailureChannel")
public interface Invocator {
    @Gateway(requestChannel="invocationChannel")
    public Boolean invokeService(Message<String> invocation);
}

@Bean
public IntegrationFlow errorHandlingFlow() {
    return IntegrationFlows
            .from("invocationFailureChannel")
            .transform("payload.getFailedMessage()")
            .handle(new GenericHandler<Object>() {
                @Override
                public Object handle(Object payload, Map<String, Object> headers) {
                    //Do Stuff
                    return false;
                }
            })
            .get();
}

错误通道的回复应该会反馈给实际调用网关的 bean,对吧?但我得到了这个奇怪的例外:

o.s.m.c.GenericMessagingTemplate$TemporaryReplyChannel - 收到回复消息,但接收线程在发送请求消息时因异常退出

我尝试为请求和回复设置超时,但这并没有真正帮助。我尝试在调用网关的代码上放置一个 try-catch,但我也没有收到错误。

我什至尝试了一个与以下所示相同的示例:

https://www.youtube.com/watch?v=mF2uq4DnVCg

我不知道为什么它不适合我。即使在示例示例中,我也会遇到相同的错误。

【问题讨论】:

    标签: java spring spring-integration


    【解决方案1】:

    当网关将错误发送到错误通道时,它有一个新的“replyChannel”标头;旧的已“用完” - 网关收到错误时使用。

    这一行...

    .transform("payload.getFailedMessage()")
    

    搞砸了,因为返回消息的转换器会覆盖标头,因此新的回复通道会被用过的通道替换。

    你可以使用

    .transform("payload.failedMessage.payload")
    

    框架将负责维护标头。如果您需要访问 failedMessage 标头,您将需要一个自定义转换器,并且您需要确保保留“新”replyChannel 标头。

    或者,您可以使用标头丰富器从失败的消息中复制单个标头 - .enrichHeaders(s -&gt; s.headerExpression("foo", "payload.failedMessage.headers['foo']")).transform() 之前。

    【讨论】:

    • 所以payload.failedMessage.payload 就像使用常规转换器行为将异常消息头映射到失败消息的技巧一样,对吗?当我有一个表达式评估出站适配器上的建议而不是常规网关上的错误通道时,这是否也适用? successChannel 和 failurechannel 是否会在标头中获取对新回复通道的引用?
    • 根据建议,还没有“新的”replyChannel - 只有当异常被抛出到网关时才会发生,网关构造了一个带有错误流回复通道的ErrorMessage。如果通知捕获异常,您将永远不会获得新的回复通道(并且根本不会调用错误流)。如果通知抛出异常(并且有一个error-channel),那么它将在通知完成其工作后发生。
    • 是的,如果转换器返回消息,框架会采取正确的行动。这只是一个约定,当转换器返回 Message&lt;?&gt; 时,假设转换器已承担全部责任。
    • 哦,所以如果我有建议,我可以在故障通道上执行transform("payload.failedMessage"),它会波回到网关,对吗?太棒了,谢谢。
    • 是的,在这种情况下,failedMessagereplyChannel 尚未使用。只是网关错误流程的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 2019-03-11
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多