我有两个组件(我们称它们为生产者和消费者)连接到同一个基于 RabbitMQ 主题的交换。
生产者可以发送两种不同的消息类型;Foo和Bar(每条消息的内容无关紧要,但我们只是说它们都有一个id字段)。每条消息使用的路由键分别是msg.foo和msg.bar。生产者不依赖默认的 Java 序列化,而是使用Jackson2JsonMessageConverter.
消费者有一个队列,该队列绑定到同一个交换器,其路由键为msg.#. 一旦被消费,所有消费者想要做的就是id在日志文件中打印每条消息。为了检索该id字段的值,需要将 JSON 有效负载转换为某种对象。
两个组件之间不共享消息类 (Foo和)。Bar消费者的对象在其消息表示中可能具有或多或少的字段。这很好,在这种情况下,任何空字段都可以设置为空。
有没有一种优雅的方法可以将这些消息从 JSON 转换/序列化为类型Foo和对象Bar?我能想出的唯一解决方案是手动编写代码来读取amqp_receivedRoutingKey或json__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 类/导入。