Spring Integration and AMQP:如何优雅地处理反序列化异常?

Posted

技术标签:

【中文标题】Spring Integration and AMQP:如何优雅地处理反序列化异常?【英文标题】:Spring Integration and AMQP: How to gracefully handle deserialization exceptions? 【发布时间】:2014-03-29 11:02:40 【问题描述】:

我使用 RabbitMQSpring 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 处理异常,这只是MessagePublishingErrorHandlererrorChannel

到目前为止一切顺利。问题是,该消息仍然被 AMQP 客户端拒绝,尽管我正在使用错误处理程序处理它。 RabbitMQ 然后一遍又一遍地重新传递消息。即使配置死信队列也无济于事。任何想法如何正确处理这种情况?

处理过程中的异常(成功反序列化后)处理得很好:AMQP 消息已确认并将错误消息发送到errorChannel

有什么想法吗?

库版本:

Spring 集成:3.0.1 Spring 框架:4.0.2 杰克逊数据绑定:2.3.1

【问题讨论】:

【参考方案1】:

您可以在侦听器容器上设置defaultRequeueRejected=false

该属性当前未在通道适配器上公开,但您可以将容器定义为 &lt;bean... class="...SimpleMessageListenerContainer"/&gt; 并使用 listener-container 属性将其注入适配器。

或者,使用一个自定义的ErrorHandler,它会抛出一个AmqpRejectAndDontRequeueException

【讨论】:

我的错,requeue-rejected 设置在使用&lt;rabbit:listener-container/&gt; 时确实可用;我忘了我们前段时间添加的。

以上是关于Spring Integration and AMQP:如何优雅地处理反序列化异常?的主要内容,如果未能解决你的问题,请参考以下文章