2017-03-21 3 views
1

Ich versuche, eine Nachricht basierend auf einem flattern MAP mit Spring Boot und AMQP zu senden. Die Nachricht sollte dann mit @RabbitListener empfangen und an ein MAP zurück übertragen werden.Spring AMQP @RabbitListener zum Ursprungsobjekt konvertieren

Zuerst habe ich JSON-String und flach verschachtelt und senden Sie es mit dem folgenden Code:

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

So weit so gut.

Auf der Empfängerseite versuche ich einen Listener zu verwenden und die Nachrichtennutzlast zurück in die Karte zu konvertieren, wie sie zuvor gesendet wurde.

Das Problem ist, dass ich keine Ahnung habe, wie es geht. erhalte ich die Nachricht mit dem folgenden Code:

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

Wie ich bereits erwähnt habe ich keine Ahnung, wie ich die Nachricht an meine alte Karte umwandeln kann. Die __ __ TypeId der Nachricht ist: com.github.wnameless.json.flattener.JsonifyLinkedHashMap

ich wäre mehr als froh, wenn mir jemand helfen könnte, wie ich diese Nachricht an eine Java-Karte zurück.

BR


Update nach Antwort von Artem Bilan:

Ich habe den folgenden Code in meine Konfigurationsdatei:

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

Aber ich habe noch keine Ahnung, wie man die Map out meiner Nachricht. Der neue Codeblock ändert nichts.

Antwort

1

Sie müssen konfigurieren Jackson2JsonMessageConverter Bean und Spring Boot wird es für die SimpleRabbitListenerContainerFactory Bean-Definition, die verwendet wird, um Listener-Container für die @RabbitListener Methoden zu bauen.

UPDATE

Achten Sie auf die Spring AMQP JSON Sample.

Es gibt eine Bohne wie jsonConverter(). Frühlings-Boot-Auto-Konfiguration Nach dieser Bean auf den Standard injiziert wird:

public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) { 

, die wirklich für die @RabbitListener standardmäßig verwendet wird, wenn das containerFactory Attribut ist leer.

Sie müssen also nur diese Bean konfigurieren und benötigen keine benutzerdefinierten SimpleRabbitListenerContainerFactory. Oder wenn Sie das tun, sollten Sie seinen Bean-Namen in diesem containerFactory Attribut Ihrer @RabbitListener Definitionen angeben.

Eine weitere Option ist wie Jackson2JsonMessageConverter.setTypePrecedence() zu berücksichtigen:

/** 
* 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) { 

Also, wenn Sie noch eine Message als Methode Argument haben wollen, aber eine Verstärkung des JSON Konvertierung auf dem __TypeId__ Header basiert, sollten Sie prüfen, Konfigurieren Sie Jackson2JsonMessageConverter basierend auf der Jackson2JavaTypeMapper.TypePrecedence.TYPE_ID.

+0

Hatten Sie eine Idee oder ein Codebeispiel, wie es geht. Ich habe darüber gelesen. Aber ich habe keine Ahnung, wie man den Nachrichtenkonverter konfiguriert, um sicherzustellen, dass er die ursprüngliche Karte, die gesendet wurde, zurückgibt. – user1796346

+0

Code Update siehe ursprünglichen Beitrag – user1796346

+0

Siehe ein Update in meiner Antwort. –

Verwandte Themen