0

我有一个service-activatorbean,它有一个获取 SI 消息列表作为输入的方法。

该方法遍历列表,从中获取每个 SI 消息,从 SI 消息中获取有效负载,然后将有效负载发送到 MQ(我没有使用任何出站通道适配器将消息发送到 MQ;我只是使用普通普通 JMS API)。

我已经<request-handler-advice-chain>在这个服务激活器上配置了一个类 asRequestHandlerRetryAdvice并将其映射到retryTemplateSimpleRetry策略配置的一个。

在该service-activator方法中,MESSAGE_SENT_STATUS如果有效负载成功发送到 MQ,我将在每个 SI 消息中添加一个带有值“SUCCESS”的标头(例如)。

EDIT1 [[ 这就是我的逻辑的样子:

 public void doSendMessage(List<Message<?> inputMsgs) {
        for(Message<?> msg : inputMsgs) {
          if(msg.getHeaders().get("MESSAGE_SENT_STATUS") != null)
              continue;
          Object payload = msg.getPayload();

          //some code logic to send 'payload' to a MQ goes here

          msg.getHeaders().put("MESSAGE_SENT_STATUS","SUCCESS");
          return;
        }
    }
//I've just typed in the code logic; so pls ignore any typos for syntax errors.

]]

我想知道这个标头是否会保留在消息中,以防出现异常并且service-activator重试该方法?

因此,例如,假设我的列表包含 3 条 SI 消息。

第一条和第二条 SI 消息已成功存放在 MQ 上(这反过来意味着这些消息MESSAGE_SENT_STATUS使用值为“SUCCESS”的标头丰富),但在尝试存放第三条 SI 消息时出现异常。

如果我在 List 的迭代中添加一个代码来检查标头MESSAGE_SENT_STATUS,并且如果它的值为“SUCCESS”然后跳过该迭代(基本上通过放置 a continue那么它会确保只有第三条消息将在 MQ 上退役?

或者这是无状态重试的情况,所有消息都将被推送到 MQ(因为MESSAGE_SENT_STATUS它们不存在)?

我还参考了手册,看看我是否可以利用ExpressionEvaluatingRequestHandlerAdvice上述用例但无法掌握它。是否可以将此建议用于我的用例?如果是的话,你能建议怎么做吗?

感谢回复!

致以真诚的感谢和诚挚的问候

4

1 回答 1

0

添加标题的逻辑

这个逻辑是什么样的?

消息(和标头的集合)是不可变的,因此您不能向现有消息“添加标头”,只能从现有消息创建新消息。

重试建议(和任何建议)只看到入站消息。

由于您的消息负载是 a Listof Messages,虽然您不能更改主消息负载本身(即更改为新的List),但您当然可以更改List负载中的内容。

所以,是的,如果您从列表元素之一创建新消息,并替换该列表元素,重试将看到更改的状态,而不是原始状态。

如果您在上游添加一个可变标头(到每个列表元素),例如 an AtomicBoolean,您可以设置该布尔值,而无需从原始消息创建新消息。

底线是,虽然消息本身是不可变的,但消息内容可以是可变的,这就是在应用程序的域中。

通常,您需要注意这方面,特别是如果将同一消息发送到多个目的地,例如使用 pub/sub 通道或收件人列表路由器,但您可以根据需要更改内容。

于 2015-10-20T12:45:46.413 回答