我尝试使用Spring Boot和AMQP基于展平MAP发送消息。然后应使用@RabbitListener接收消息并将其传回MAP。
首先,我嵌套了json String并将其展平并使用以下代码发送它:
// Flatten the JSON String returned into a map
Map<String,Object> jsonMap = JsonFlattener.flattenAsMap(result);
rabbitTemplate.convertAndSend(ApplicationProperties.rmqExchange, ApplicationProperties.rmqTopic, jsonMap, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("amqp_Key1", "wert1");
message.getMessageProperties().setHeader("amqp_Key2", "Wert2");
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
return message;
}
});
到目前为止一切顺利。
在接收站点上,我尝试使用监听器,并将消息有效负载转换回以前发送的映射。
问题在于我不知道该怎么做。 我收到的消息包含以下代码:
@RabbitListener(queues = "temparea")
public void receiveMessage(Message message) {
log.info("Receiving data from RabbitMQ:");
log.info("Message is of type: " + message.getClass().getName());
log.info("Message: " + message.toString());
}
正如我之前提到的,我不知道如何将消息转换为旧MAP。消息的__ TypeId __是:com.github.wnameless.json.flattener.JsonifyLinkedHashMap
如果有人能帮助我将这条消息发回Java地图,我会非常高兴。
BR
Artem Bilan回答后更新:
我在配置文件中添加了以下代码:
@Bean
public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setMessageConverter(new Jackson2JsonMessageConverter());
factory.setConnectionFactory(connectionFactory());
factory.setMaxConcurrentConsumers(5);
return factory;
}
但我仍然不知道如何从我的信息中获取地图。 新代码块不会改变任何内容。
答案 0 :(得分:1)
您必须配置Jackson2JsonMessageConverter
bean,Spring Boot将为SimpleRabbitListenerContainerFactory
bean定义选择它,该定义用于构建@RabbitListener
方法的侦听器容器。
<强>更新强>
有像jsonConverter()
这样的bean。根据Spring Boot自动配置,这个bean被注入默认值:
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
当@RabbitListener
属性为空时,默认情况下,containerFactory
实际使用了哪个。
因此,您只需配置该bean并且不需要任何自定义SimpleRabbitListenerContainerFactory
。或者,如果您这样做,则应在containerFactory
定义的@RabbitListener
属性中指定其bean名称。
另一个需要考虑的选择是Jackson2JsonMessageConverter.setTypePrecedence()
:
/**
* Set the precedence for evaluating type information in message properties.
* When using {@code @RabbitListener} at the method level, the framework attempts
* to determine the target type for payload conversion from the method signature.
* If so, this type is provided in the
* {@link MessageProperties#getInferredArgumentType() inferredArgumentType}
* message property.
* <p> By default, if the type is concrete (not abstract, not an interface), this will
* be used ahead of type information provided in the {@code __TypeId__} and
* associated headers provided by the sender.
* <p> If you wish to force the use of the {@code __TypeId__} and associated headers
* (such as when the actual type is a subclass of the method argument type),
* set the precedence to {@link TypePrecedence#TYPE_ID}.
* @param typePrecedence the precedence.
* @since 1.6
* @see DefaultJackson2JavaTypeMapper#setTypePrecedence(Jackson2JavaTypeMapper.TypePrecedence)
*/
public void setTypePrecedence(Jackson2JavaTypeMapper.TypePrecedence typePrecedence) {
因此,如果您仍希望将Message
作为方法参数但是根据__TypeId__
标头获得JSON转换,则应考虑将Jackson2JsonMessageConverter
配置为基于Jackson2JavaTypeMapper.TypePrecedence.TYPE_ID
。