我的设置:
我有一个使用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,并在代理上确认消息。当您没有交易时,也会发生同样的情况。