RabbitMQ + Spring集成:从队列到主题交换的消息转换

时间:2019-09-08 10:38:09

标签: java rabbitmq spring-integration spring-amqp spring-rabbitmq

我有两个组件(分别称为生产者和消费者)连接到同一RabbitMQ基于主题的交换。

生产者可以发送两种不同的消息类型; FooBar(每条消息的内容无关紧要,但我们都说它们都具有一个id字段)。用于每个消息的路由密钥分别为msg.foomsg.bar。生产者没有使用默认的Java序列化,而是使用Jackson2JsonMessageConverter

使用者有一个队列,该队列使用msg.#的路由键绑定到同一交换机。一旦使用完毕,所有使用者将要做的就是在日志文件中打印每条消息的id。为了检索id字段的值,需要将JSON有效负载转换为某种对象。

这两个组件之间没有共享消息类(FooBar)。消费者的对象在其消息表示中可能具有更多或更少的字段。很好,在这种情况下,任何空字段都可以设置为null。

是否存在一种优雅的方法将这些消息从JSON转换/序列化为FooBar类型的对象?我唯一能想到的解决方案是手动编写读取amqp_receivedRoutingKeyjson__TypeId__标头的代码,以确定对象类型。示例:

@Bean
public IntegrationFlow inbound(ConnectionFactory connectionFactory, Queue queue) {
    return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, queue))
        .handle(message -> {
            final byte[] payload = (byte[]) message.getPayload();
            final String payloadStr = new String(payload, Charset.defaultCharset());

            final String routingKey = (String) message.getHeaders().get("amqp_receivedRoutingKey");

            try {
                if (routingKey.equals("msg.foo")) {
                    final Foo foo = new Jackson2JsonObjectMapper().fromJson(payloadStr, Foo.class);

                    System.out.println("FOO id: " + foo.getId());
                } else if (routingKey.equals("msg.bar")) {
                    final Bar bar = new Jackson2JsonObjectMapper().fromJson(payloadStr, Bar.class);

                    System.out.println("BAR id: " + bar.getId());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        })
        .get();
}

不幸的是,由于重复使用if / else子句,因此非常不完整,也很丑陋。我是否缺少任何Spring Integration技巧,这些技巧会使我的代码更具可读性?

我设法找到了一个类似的问题(spring boot rabbitmq MappingJackson2MessageConverter custom object conversion),但是除了解决方案不起作用之外,它还是RabbitMQ特有的。我宁愿不熟悉RabbitMQ,并尽可能使用标准AMQP类/导入。

1 个答案:

答案 0 :(得分:0)

您似乎错过了Jackson2JsonMessageConverter填充AMQP消息中相应标题的事实。并且可以依靠这些标头在消费者端恢复POJO。

因此,请考虑同时为Amqp.inboundAdapter(connectionFactory, queue)配置Jackson2JsonMessageConverter

在文档中查看有关转换器的更多信息:https://docs.spring.io/spring-amqp/docs/2.2.0.RC1/reference/html/#json-message-converter