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

春季配置:
收到消息后,将执行以下步骤:
1.转换器:将json转换为pojo
2.有效负载类型路由器:根据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) {...}
}


问题:


我想知道如何在服务激活器中访问消息头。似乎服务激活器无法访问消息头,因为转换器正在返回pojo。
可以说服务激活器无论出于何种原因都无法调用下游休息服务。我现在想跳过处理此消息,以后再重试此消息。或者说在处理此消息时有异常。我想在延迟一段时间后重试处理此消息。我该如何完成?


- 编辑 -
根据Artem的评论,删除了详细信息以减小问题的大小。

最佳答案

请,请不要在SO中做那么长的主题。如果其中有很多,则很难回答特定的问题。

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

即使您的转换器方法仅返回一个POJO,也不意味着它不会被requestMessage的头包装到Message中。如果您需要随POJO一起返回特定的标头,则应该使用Message自己创建MessageBuilder,不要忘记复制requestMessage标头,因为在返回整个消息的情况下,转换器不会复制请求标头。

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

08-18 10:37
查看更多