處理例外狀況
預設情況下,如果註解監聽器方法拋出例外狀況,它會被拋給容器,而訊息會根據容器和 Broker 設定重新排隊並重新傳遞、丟棄或路由到死信交換器。不會傳回任何內容給發送者。
從 2.0 版本開始,`@RabbitListener` 註解有兩個新屬性:`errorHandler` 和 `returnExceptions`。
這些預設未設定。
您可以使用 `errorHandler` 來提供 `RabbitListenerErrorHandler` 實作的 Bean 名稱。此函數介面有一個方法,如下所示
@FunctionalInterface
public interface RabbitListenerErrorHandler {
Object handleError(Message amqpMessage, org.springframework.messaging.Message<?> message,
ListenerExecutionFailedException exception) throws Exception;
}
如您所見,您可以存取從容器接收的原始訊息、訊息轉換器產生的 spring-messaging `Message>` 物件,以及監聽器拋出的例外狀況(封裝在 `ListenerExecutionFailedException` 中)。錯誤處理常式可以傳回一些結果(作為回覆傳送),或者拋出原始或新的例外狀況(根據 `returnExceptions` 設定,拋給容器或傳回給發送者)。
`returnExceptions` 屬性為 `true` 時,會導致例外狀況傳回給發送者。例外狀況會封裝在 `RemoteInvocationResult` 物件中。在發送者端,有一個可用的 `RemoteInvocationAwareMessageConverterAdapter`,如果配置到 `RabbitTemplate` 中,它會重新拋出伺服器端例外狀況,並封裝在 `AmqpRemoteException` 中。伺服器例外狀況的堆疊追蹤是透過合併伺服器和用戶端堆疊追蹤來合成的。
此機制通常僅適用於預設的 `SimpleMessageConverter`,它使用 Java 序列化。例外狀況通常不「Jackson 友善」,且無法序列化為 JSON。如果您使用 JSON,請考慮使用 `errorHandler` 在拋出例外狀況時傳回一些其他 Jackson 友善的 `Error` 物件。 |
在 2.1 版本中,此介面從套件 `o.s.amqp.rabbit.listener` 移至 `o.s.amqp.rabbit.listener.api`。 |
從 2.1.7 版本開始,`Channel` 在訊息傳遞訊息標頭中可用;這允許您在使用 `AcknowledgeMode.MANUAL` 時確認或否定失敗的訊息。
public Object handleError(Message amqpMessage, org.springframework.messaging.Message<?> message,
ListenerExecutionFailedException exception) {
...
message.getHeaders().get(AmqpHeaders.CHANNEL, Channel.class)
.basicReject(message.getHeaders().get(AmqpHeaders.DELIVERY_TAG, Long.class),
true);
}
從 2.2.18 版本開始,如果拋出訊息轉換例外狀況,將會呼叫錯誤處理常式,且 `message` 引數中為 `null`。這允許應用程式將一些結果傳送給呼叫者,指出已接收到格式錯誤的訊息。先前,此類錯誤會被拋出並由容器處理。