1

我的设置:
我有一个使用 ActiveMQ 的消息守护程序,它将使用 JSON 消息。
JSON消息的发布者添加type带有值的标头,例如,com.example.Foo这是json消息的类型。我用它来将 json 转换为 pojo。

Spring config:
收到消息后,将执行以下步骤:
1. Transformer:将 json 转换为 pojo
2. Payload type router:根据 pojo 的类型,将 pojo 路由到适当的服务激活器。
3.服务激活器:处理消息。

<int:chain input-channel="transformerChannel">
    <int:transformer id="jsonToPojoTransformer" ref="JsonToPojoTransformer" method="transform" />

    <int:payload-type-router default-output-channel="defaultChannel">
        <int:mapping type="com.example.Foo" channel="fooHandlerChannel"/>
        <int:mapping type="com.example.Bar" channel="barHandlerChannel"/>
    </int:payload-type-router>
</int:chain>

<int:service-activator input-channel="fooHandlerChannel" ref="fooHandler" method="onMessage"/>
<int:service-activator input-channel="barHandlerChannel" ref="barHandler" method="onMessage"/>

服务激活器定义:

public class FooHandler {
    public void onMessage(Foo foo) {...}
}

问题:

  1. 我想知道如何访问服务激活器中的消息头。似乎服务激活器无法访问消息标头,因为转换器正在返回一个 pojo。

  2. 假设服务激活器无论出于何种原因都无法调用下游休息服务。我现在想跳过处理这条消息,我想稍后重试这条消息。或者可以说处理此消息时出现异常。我想在延迟一段时间后重试处理此消息。我该如何做到这一点?

--edit--
根据 Artem 的评论,删除了细节以减少问题的大小。

4

1 回答 1

0

请尽量不要在 SO 中提出这么长的主题。如果有很多问题,很难回答特定问题。

绝对不清楚为什么您无法从服务激活器方法访问标头。您可以接受整个Message<>,并调用其getHeaders(). You can use@Headers annotation on theMap arg to get headers from the message. You can use@Header` 注释以从消息中准确提取特定的标头。

即使您的转换器方法仅返回一个 POJO,但这并不意味着它没有Message使用 requestMessage 的标头包装到。如果您需要与 POJO 一起返回特定的标头,您应该创建Message自己,使用MessageBuilder并且不要忘记复制 requestMessage 标头,因为如果返回整个消息,转换器不会复制请求标头。

您必须在您的 JMS 使用者上支持 TX,这RuntimeException将导致回滚,因此最终会重新交付。并且您应该确保所有流程都在同一个线程中执行。否则提交 TX 并在代理上确认消息。当您没有交易时也会发生同样的情况。

于 2017-06-29T21:32:58.553 回答