Как прочитать заголовок x-death недоставленного сообщения RabbitMQ с помощью Spring Boot?

Я пытаюсь реализовать перенаправление недоставленных сообщений, как описано в этом ответе. Я использую конфигурацию Spring. Я понятия не имею, как читать заголовки, чтобы получить исходный ключ маршрутизации и исходную очередь. Ниже приведен мой конфиг:

@Configuration
public class NotifEngineRabbitMQConfig {
    @Bean
    public MessageHandler handler(){
        return new MessageHandler();
    }
    @Bean
    public Jackson2JsonMessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    @Bean
    public MessageListenerAdapter messageListenerAdapter(){
        return new MessageListenerAdapter(handler(), messageConverter());
    }

    /**
     * Listens for incoming messages
     * Allows multiple queue to listen to
     * */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.addQueueNames(QUEUE_TO_LISTEN_TO.split(","));
        container.setMessageListener(messageListenerAdapter());
        container.setConnectionFactory(rabbitConnectionFactory());
        container.setDefaultRequeueRejected(false);
        return container;
    }

    @Bean
    public ConnectionFactory rabbitConnectionFactory(){
        CachingConnectionFactory factory = new CachingConnectionFactory(HOST);
        factory.setUsername(USERNAME);
        factory.setPassword(PASSWORD);
        return factory;
    }

}

person nikkidtosh    schedule 02.06.2016    source источник


Ответы (2)


Заголовки недоступны при обмене сообщениями Pojo в «старом» стиле (с MessageListenerAdapter). Вам нужно реализовать MessageListener, который дает вам доступ к заголовкам.

Однако в этом случае вам нужно будет вызвать преобразователь самостоятельно, и, если вы используете обмен сообщениями типа запрос/ответ, вы потеряете механизм ответа в адаптере, и вам придется отправлять ответ самостоятельно.

В качестве альтернативы вы можете использовать пользовательский преобразователь сообщений и «дополнить» преобразованный объект заголовком после вызова стандартного преобразователя.

Вместо этого рассмотрите возможность использования более нового стиля обмена сообщениями POJO с @RabbitListener — он дает вам доступ к заголовкам и имеет возможность запроса/ответа.

Вот пример:

@SpringBootApplication
public class So37581560Application {

    public static void main(String[] args) {
        SpringApplication.run(So37581560Application.class, args);
    }

    @Bean
    public FooListener fooListener() {
        return new FooListener();
    }

    public static class FooListener {

        @RabbitListener(queues="foo")
        public void pojoListener(String body, 
                   @Header(required = false, name = "x-death") List<String> xDeath) {
            System.out.println(body + ":" + (xDeath == null ? "" : xDeath));
        }

    }

}

Результат:

Foo:[{reason=expired, count=1, exchange=, time=Thu Jun 02 08:44:19 EDT 2016, routing-keys=[bar], queue=bar}]
person Gary Russell    schedule 02.06.2016

Ответ Гэри правильный. Маленькая деталь, тип xDeath лучше ArrayList<HashMap<String,*>> вместо List<String> xDeath. Затем вы можете получить доступ к любому полю, выполнив что-то вроде: xDeath.first().get("count")

person josemmg    schedule 23.11.2017