Spring集成 - 在失败时装饰消息

时间:2015-09-21 13:43:21

标签: java spring jms activemq spring-integration

我正在尝试实现一个由几个webservice调用组成的进程,由Spring-integration读取的JMS消息启动。由于这些WS调用之间没有事务,因此我想跟踪我的进程已经走了多远,以便在重试消息处理时跳过已执行的步骤。

示例步骤:

  1. 检索A(获取A.id)
  2. 为A创建新B(使用A.id,获取B.id)
  3. 为B创建新的C(使用B.id,获得C.id)
  4. 现在,如果第一次尝试在步骤3中失败,我已经创建了一个B,并且知道了它的ID。因此,如果我想重试该消息,它将跳过第二步,并且不会给我留下不完整的B。

    那么,问题是:是否有可能在消息处理失败时装饰Spring兼容读取的JMS消息以及其他标头属性?如果是这样,我怎么能这样做?

    目前的工作方式:

    1. 阅读消息
    2. 抛出一些异常
    3. 消息处理暂停,ActiveMQ将消息放在DLQ上
    4. 我希望它如何工作:

      1. 阅读消息
      2. 抛出一些异常
      3. 处理异常,此处理的结果是添加到原始消息的额外标头属性
      4. ActiveMQ将消息放在DLQ上
      5. 可能实现这一目标的有以下几点:

        1. 阅读消息
        2. 开始处理,包含在try-catch中
        3. 在例外情况下,从异常中获取额外信息,根据原始消息创建新消息,向标题添加额外信息并将其直接发送到DLQ
        4. 吞下该异常,使原始消息消失
        5. 虽然这有点像个hackish,希望有一个更优雅的解决方案。

2 个答案:

答案 0 :(得分:1)

如果没有关于您的流的更多信息,很难概括,但您可以考虑添加自定义请求处理程序建议来装饰和/或重新路由失败的消息。请参阅Adding Behavior to Endpoints

正如另一个答案所说,您无法修改消息,但可以从中构建新消息。

修改

  

那么,问题是:是否有可能在消息处理失败时装饰Spring兼容读取的JMS消息以及其他标头属性?如果是这样,我怎么能这样做?

啊啊......现在我想我知道你在问什么;不,你不能“装饰”现有的消息;您可以使用其他标头重新发布它,而不是抛出异常。

您可以在建议或错误流程中重新发布。

对你来说这似乎是一个“黑客”,但JMS API没有提供你想要的机制。

答案 1 :(得分:0)

从春天forum

  

要将新标题放入您应该使用的MessageHeaders   MessageBuilder,因为不仅是标题,而是整个Message   不可变的。

return MessageBuilder.fromMessage(message).setHeader(updateflag, message.getHeaders().get("Lgg_Rid") == "ACK" ? "CONF" : "FAIL").build();

在异步上下文中,错误将转到错误通道 - 您自己配置并在消息头中指示errorChannel,或者如果未指定则指示全局错误通道。有关详细信息,请参阅here