2017-03-21 60 views
1

我尝试使用Spring Boot和AMQP基于展平的MAP发送消息。然后应该使用@RabbitListener接收消息并将其传回MAP。Spring AMQP @RabbitListener转换为原始对象

首先,我有嵌套的JSON字符串和平板,并使用下面的代码发送:

// 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()); 
    } 

正如我之前提到的,我不知道我是如何将消息转换到我的旧地图。消息的__ TypeId __是:com.github.wnameless.json.flattener.JsonifyLinkedHashMap

如果有人能帮助我如何将此消息返回给Java地图,我将非常高兴。

从阿尔乔姆比兰回答后BR


更新:

我下面的代码添加到我的配置文件:

@Bean 
public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() { 
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); 
    factory.setMessageConverter(new Jackson2JsonMessageConverter()); 
    factory.setConnectionFactory(connectionFactory()); 
    factory.setMaxConcurrentConsumers(5); 
    return factory; 
} 

但我仍然不知道如何获得映射出我的消息。 新的代码块不会改变任何东西。

回答

1

您必须配置Jackson2JsonMessageConverter bean,并且Spring Boot将为SimpleRabbitListenerContainerFactory bean定义提取它,该定义用于为@RabbitListener方法构建侦听器容器。

UPDATE

,请注意Spring AMQP JSON Sample

有一个像jsonConverter()豆。根据春天开机自动配置这个bean被注入到默认:

public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) { 

这是真正用于@RabbitListener默认情况下,当containerFactory属性为空。

因此,您只需配置该bean并且不需要任何自定义SimpleRabbitListenerContainerFactory。或者如果你这样做,你应该在你的@RabbitListener定义的containerFactory属性中指定它的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

+0

你有一个想法或代码示例如何做到这一点。我读了这个。但我不知道如何配置消息转换器以确保它将返回发送的原始Map。 – user1796346

+0

代码更新请参阅原始文章 – user1796346

+0

查看我答案中的更新。 –

相关问题