Java Spring集成,将无效消息全局转移到其他目的地 设置
我有一个JMS消息传递应用程序,其中包含来自多个JMS目的地的入站消息。消息有效负载是不同的JSON表示形式,带有一些常见的头。我依靠Spring在Java Spring集成,将无效消息全局转移到其他目的地 设置,java,spring,spring-integration,enterprise-integration,Java,Spring,Spring Integration,Enterprise Integration,我有一个JMS消息传递应用程序,其中包含来自多个JMS目的地的入站消息。消息有效负载是不同的JSON表示形式,带有一些常见的头。我依靠Spring在ServiceActivators上的动态Jackson类型转换来转换为实际的POJO。目前,路由很简单,因为通道本质上是由JSON有效负载类型分割出来的“数据类型”通道(它们都是JSON字符串有效负载,但JSON表示非常不同的对象类型) 问题 我希望将全局验证逻辑应用于多个模式匹配通道(例如,“*input*”)中的所有入站消息,并将无效消息转移到
ServiceActivators
上的动态Jackson类型转换来转换为实际的POJO。目前,路由很简单,因为通道本质上是由JSON有效负载类型分割出来的“数据类型”通道(它们都是JSON字符串有效负载,但JSON表示非常不同的对象类型)
问题
我希望将全局验证逻辑应用于多个模式匹配通道(例如,“*input*”
)中的所有入站消息,并将无效消息转移到验证错误通道进行审查。无论消息是否有效,都应提交本地JMS事务;如果消息无效,我不希望以后重新发送无效消息
考虑的潜在选择
信道拦截器
我最初的想法是实现一个ChannelInterceptor
,它匹配应该应用此逻辑的所有通道,但似乎无法在ChannelInterceptor
中实现消息转移功能。看来我使用ChannelInterceptor
的两个选项是:
preSend
上返回null时回滚JMS事务,或者路由器
可能是一个不错的选择,但似乎没有办法将路由器应用于模式匹配的通道集,因此我相信我必须将其分别应用于每个通道。我希望避免这种重复
AspectJ切入点
我想到的另一个选择是突破AspectJ,在AbstractMessageSendingTemplate.convertAndSend(目的地、有效负载、后处理器)
方法上实现@Around
建议。这似乎很烦人,但似乎可行。如果有一个更能直接得到框架支持的选项,我很乐意听到
带有效负载路由的公共输入信道
如果我找不到全局应用这种路由逻辑的方法,那么另一种选择可能是通过单个通道路由所有入站JMS消息。自定义路由器
可应用于该入站通道,该入站通道使用有效负载类型头将消息定向到其正确的“数据类型”通道,并将无效消息路由到验证错误通道
问题
- 有没有办法将这种类型的消息转移应用到模式匹配的通道集李>
- 我是否错过了Spring集成框架的一个重要功能,它将使我的考虑之一发挥作用李>
- 如果没有,是否有比我提到的更好的EIP选项
preSend()
可以返回null
,有效终止操作;只需将失败的验证发送到公共通道并返回null
/**
* Invoked before the Message is actually sent to the channel.
* This allows for modification of the Message if necessary.
* If this method returns {@code null} then the actual
* send invocation will not occur.
*/
@Nullable
default Message<?> preSend(Message<?> message, MessageChannel channel) {
return message;
}
/**
*在消息实际发送到通道之前调用。
*这允许在必要时修改消息。
*如果此方法返回{@code null},则实际
*发送调用将不会发生。
*/
@可空
默认消息呈现(消息消息、消息通道){
返回消息;
}
这将导致入站适配器出现MessageDeliveryException
,但您可以简单地将其吸收到错误通道流中
我最初的想法是实现一个ChannelInterceptor,它匹配应该应用此逻辑的所有通道,但似乎不能在ChannelInterceptor中实现消息转移功能
是什么让你相信的preSend()
可以返回null
,有效终止操作;只需将失败的验证发送到公共通道并返回null
/**
* Invoked before the Message is actually sent to the channel.
* This allows for modification of the Message if necessary.
* If this method returns {@code null} then the actual
* send invocation will not occur.
*/
@Nullable
default Message<?> preSend(Message<?> message, MessageChannel channel) {
return message;
}
/**
*在消息实际发送到通道之前调用。
*这允许在必要时修改消息。
*如果此方法返回{@code null},则实际
*发送调用将不会发生。
*/
@可空
默认消息呈现(消息消息、消息通道){
返回消息;
}
这将导致入站适配器出现
MessageDeliveryException
,但您可以简单地将其吸收到错误通道流中。我的位置在全局ChannelInterceptor
中不这样做,因为它很容易陷入通道模式,而该通道不应受到这种过滤逻辑的影响
您始终可以将所有消息发送到同一通道,以实现公共逻辑。在发送到验证通道之前,您可以通过replyChannel
标题来控制路由行为。所以,对我来说,逻辑是这样的:
header
,用流中所需的下一步填充replyChannel
头过滤器
组件过滤器的丢弃通道
,如您所述