1

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

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

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

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

有没有一种优雅的方法可以将这些消息从 JSON 转换/序列化为类型Foo和对象Bar?我能想出的唯一解决方案是手动编写代码来读取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 类/导入。

4

1 回答 1

0

您似乎错过了Jackson2JsonMessageConverter在 AMQP 消息中填充适当标头的事实。而这个可以依靠这些标头在消费者端恢复 POJO。

因此,请考虑配置您Amqp.inboundAdapter(connectionFactory, queue)的 aJackson2JsonMessageConverter为好。

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

于 2019-09-09T13:54:39.987 回答