Spring Integration - Java DSL中的AMQP推断类型?

问题描述 投票:1回答:1

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

我们在生产者和消费者方面使用Jackson2JsonMessageConverter,我们正在使用Java DSL来连接队列中的流。

我确信有一种方法可以做到这一点,但它正在逃避我:我希望消费者方忽略从生产者传递的__TypeID__标题,因为消费者可能对该事件有不同的表示(并且很可能在一个不同的java包中)。

似乎已完成工作,如果使用注释@RabbitListener,则会导出inferredArgumentTypeargument并覆盖标题信息。这正是我想要做的,但我想使用Java DSL来做。我还没有找到一个干净的方式来做这件事,也许我只是遗漏了一些明显的东西。在使用以下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;
            }
        });
    }
}

我真的希望得到这个,所以开发人员不必真正处理这个问题。

有更简单的方法吗?

spring-integration spring-integration-dsl
1个回答
1
投票

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

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

然后,__TypeId__标头得到foo,接收系统将它映射到它的Foo的表示。

编辑

另一种选择是将afterReceiveMessagePostProcessor添加到入站通道适配器的侦听器容器中 - 它可以更改__TypeId__标头。

© www.soinside.com 2019 - 2024. All rights reserved.