Spring AMQP @RabbitListener转换为origin对象

时间:2017-03-21 21:06:04

标签: spring spring-boot rabbitmq

我尝试使用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;
}

但我仍然不知道如何从我的信息中获取地图。 新代码块不会改变任何内容。

1 个答案:

答案 0 :(得分:1)

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

<强>更新

注意Spring AMQP JSON Sample

有像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