Интеграция Spring и AMQP: как изящно обрабатывать исключения десериализации?

Я использую RabbitMQ и Spring Integration для обработки входящих сообщений JSON.

Соответствующая часть конфигурации выглядит примерно так:

<amqp:inbound-channel-adapter channel="incomingChannel" queue-names="..."
      message-converter="jsonConverter" error-handler="errorHandler"
      error-channel="errorChannel" />

Я использую Jackson Databind в качестве конвертера JSON.

Иногда входящие сообщения JSON имеют неправильный синтаксис. Это приводит к следующему (правильному) исключению:

org.springframework.amqp.rabbit.listener.ListenerExecutionFailedException: Listener threw exception
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Failed to convert Message content
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_ARRAY token...

Затем исключение обрабатывается errorHandler, который просто является от MessagePublishingErrorHandler до errorChannel.

Все идет нормально. Проблема в том, что сообщение все еще отклоняется клиентом AMQP, хотя я обрабатываю его с помощью обработчика ошибок. RabbitMQ затем повторно доставляет сообщение снова и снова. Даже настройка очереди недоставленных сообщений не помогла. Есть идеи, как правильно справиться с этим сценарием?

Исключения, находящиеся ниже в обработке (после успешной десериализации), обрабатываются нормально: сообщение AMQP подтверждено, а сообщение об ошибке отправляется на errorChannel.

Любые идеи?

Версии библиотеки:

  • Интеграция Spring: 3.0.1
  • Spring Framework: 4.0.2
  • Данные Джексона: 2.3.1

person Philipp Jardas    schedule 26.02.2014    source источник


Ответы (1)


Вы можете установить defaultRequeueRejected=false в контейнере слушателя.

Атрибут в настоящее время не отображается в адаптере канала, но вы можете определить контейнер как <bean... class="...SimpleMessageListenerContainer"/> и вставить его в адаптер с помощью атрибута listener-container.

Или используйте пользовательский ErrorHandler, который выдает AmqpRejectAndDontRequeueException.

person Gary Russell    schedule 26.02.2014
comment
Моя ошибка, настройка requeue-rejected действительно доступна при использовании <rabbit:listener-container/>; Я забыл, что мы добавили его некоторое время назад. - person Gary Russell; 08.03.2014