Spring integration Spring集成——JavaDSL中的AMQP推断类型?

Spring integration Spring集成——JavaDSL中的AMQP推断类型?,spring-integration,spring-integration-dsl,Spring Integration,Spring Integration Dsl,我一直在为使用AMQP在两个微服务之间建立异步消息传递“铺平道路”。我们希望为每个服务推广使用单独的域对象,这意味着每个服务必须定义它们自己的通过队列传递的任何对象的副本 我们在生产者和消费者端都使用了Jackson2JsonMessageConverter,并且我们使用javadsl将流连接到队列或从队列连接到队列 我确信有一种方法可以做到这一点,但我还是没有意识到:我希望消费者端忽略从生产者传递的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

我一直在为使用AMQP在两个微服务之间建立异步消息传递“铺平道路”。我们希望为每个服务推广使用单独的域对象,这意味着每个服务必须定义它们自己的通过队列传递的任何对象的副本

我们在生产者和消费者端都使用了
Jackson2JsonMessageConverter
,并且我们使用javadsl将流连接到队列或从队列连接到队列

我确信有一种方法可以做到这一点,但我还是没有意识到:我希望消费者端忽略从生产者传递的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
头,因为消费者可能对该事件有不同的表示

如果使用注释
@RabbitListener
,则会派生
inferredArgumentType
参数,并将覆盖标题信息。这正是我想做的,但我想使用JavaDSL来做。我还没有找到一个干净的方法来做到这一点,也许我只是错过了一些明显的东西。在使用以下DSL时,派生类型似乎是相当直接的:

return IntegrationFlows
        .from(
                Amqp.inboundAdapter(factory, queueRemoteTaskStatus())
                        .concurrentConsumers(10)
                        .errorHandler(errorHandler)
                        .messageConverter(messageConverter)
        )
        .channel(channelRemoteTaskStatusIn())
        .handle(listener, "handleRemoteTaskStatus")
        .get();
但是,这会导致
ClassNotFound
异常。到目前为止,我发现解决这个问题的唯一方法是设置一个自定义消息转换器,它需要显式定义类型

public class ForcedTypeJsonMessageConverter extends Jackson2JsonMessageConverter {

    ForcedTypeJsonMessageConverter(final Class<?> forcedType) {
        setClassMapper(new ClassMapper() {

            @Override
            public void fromClass(Class<?> clazz, MessageProperties properties) {
                    //this class is only used for inbound marshalling.
            }

            @Override
            public Class<?> toClass(MessageProperties properties) {
                return forcedType;
            }
        });
    }
}
public类ForcedTypeJsonMessageConverter扩展了Jackson2JsonMessageConverter{
ForcedTypeJsonMessageConverter(最终类forcedType){
setClassMapper(新类映射器(){
@凌驾
来自类的公共void(类clazz、MessageProperties){
//此类仅用于入站编组。
}
@凌驾
公共类到类(MessageProperties属性){
返回强制类型;
}
});
}
}
我真的希望这是衍生出来的,所以开发人员不必真正处理这个问题


有没有更简单的方法

最简单的方法是使用
TypeIdMapping
setIdClassMapping()
)配置Jackson转换器的
DefaultJackson2JavaTypeMapper

在发送系统上,映射为
foo:com.one.foo
,在接收系统上映射为
foo:com.two.foo

然后,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

编辑


另一个选项是在入站通道适配器的侦听器容器中添加
afterReceiveMessagePostProcessor
——它可以更改
\uuuuuuTypeId\uuuuuuuuu
头。

对不起,我遗漏了一些内容,但我不明白在该流定义中如何“直接”派生类型?感谢在转换器的类型映射器中使用类型id映射(
setIdClassMapping
)。请看我的答案。我猜“直截了当”是一个错误的术语,如果内容类型是application/json,而不必显式定义特定类型的映射策略,那么我需要隐式处理类型。这与这里讨论的想法类似:。如果我删除producer端的typeId,而只保留application/json,那么最好使用“开箱即用”封送处理?使用
@RabbitListener
我们知道方法参数的类型。当使用入站有效负载创建通用消息时,无法推断有效负载的类型,因为创建消息的组件与使用消息的方法完全解耦。因此,您必须为转换器配置负载类型的某种提示。我给我的答案增加了另一个选项。谢谢完全有意义,谢谢你的解释