2017-03-21 59 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

查看我答案中的更新。 –

相關問題