Есть ли способ добавить обработчик ошибок или обработчик исключений в SqsListener?

#java #json #spring #spring-boot #amazon-sqs

#java #json #spring #весенняя загрузка #amazon-sqs

Вопрос:

У меня есть SqsListener, использующий пользовательский QueueMessageHandlerFactory с преобразователем сообщений для перехода из JSON в POJO и обратно. Если по какой-либо причине метод listener не может проанализировать тело JSON в сообщении, он выдаст org.springframework.messaging.converter .Исключение MessageConversionException. Я хочу перехватить это исключение и правильно его зарегистрировать. Я знаю, что прослушиватели JMS позволяют добавлять пользовательский обработчик ошибок как часть заводского определения.

Есть ли аналогичный способ определить пользовательский обработчик ошибок, чтобы перехватить это исключение с помощью SqsListener Spring и зарегистрировать его?

Спасибо!

   @Bean
  public QueueMessageHandlerFactory queueMessageHandlerFactory(MessageConverter messageConverter) {
    QueueMessageHandlerFactory factory = new QueueMessageHandlerFactory();
    AcknowledgmentHandlerMethodArgumentResolver acknowledgmentResolver =
        new AcknowledgmentHandlerMethodArgumentResolver(
            ACKNOWLEDGMENT_HEADER_NAME);
    PayloadArgumentResolver payloadArgumentResolver = new PayloadArgumentResolver(messageConverter);
    factory.setArgumentResolvers(Arrays.asList(acknowledgmentResolver, payloadArgumentResolver));
    return factory;
  }

  @Bean
  protected MessageConverter messageConverter(ObjectMapper objectMapper) {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setObjectMapper(objectMapper);
    converter.setStrictContentTypeMatch(false);
    return converter;
  }

 

Слушатель:

 
 @SqsListener(value = "${aws.sqs.queueName}", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
  public void receiveMessage(MyCustomPOJO pollo, Acknowledgment acknowledgment) {
    LOG.info("Message Received using SQS Listener "   pollo);
    try {
      acknowledgment.acknowledge().get();
    } catch (InterruptedException | ExecutionException e) {
      LOG.error("Error acknowledging message: "   pollo);
    }
  }

 

Исключение, вызванное отправкой «тестового сообщения» вместо десериализованного POJO.

 org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Unrecognized token 'Test': was expecting ('true', 'false' or 'null')
 at [Source: Test Message!; line: 1, column: 5]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Test': was expecting ('true', 'false' or 'null')
 at [Source: Test Message!; line: 1, column: 5]
    at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertFromInternal(MappingJackson2MessageConverter.java:224) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.converter.AbstractMessageConverter.fromMessage(AbstractMessageConverter.java:175) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:135) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:112) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:135) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:107) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:502) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:461) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:399) [spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.executeMessage(SimpleMessageListenerContainer.java:228) [spring-cloud-aws-messaging-2.2.4.RELEASE.jar:2.2.4.RELEASE]
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.run(SimpleMessageListenerContainer.java:418) [spring-cloud-aws-messaging-2.2.4.RELEASE.jar:2.2.4.RELEASE]
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$SignalExecutingRunnable.run(SimpleMessageListenerContainer.java:310) [spring-cloud-aws-messaging-2.2.4.RELEASE.jar:2.2.4.RELEASE]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_251]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_251]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_251]
Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Test': was expecting ('true', 'false' or 'null')
 at [Source: Test Message!; line: 1, column: 5]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1702) ~[jackson-core-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:558) ~[jackson-core-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2839) ~[jackson-core-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1903) ~[jackson-core-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:749) ~[jackson-core-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3834) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3783) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2880) ~[jackson-databind-2.8.7.jar:2.8.7]
    at org.springframework.messaging.converter.MappingJackson2MessageConverter.convertFromInternal(MappingJackson2MessageConverter.java:219) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    ... 14 more
 

Ответ №1:

Неважно, похоже, все, что мне нужно сделать, это добавить аннотацию @MessageExceptionHandler в мой пользовательский обработчик:

   @MessageExceptionHandler(MessageConversionException.class)
  public void exceptionHandler(MessageConversionException e) {
    LOG.info("Failed to deserialize that pollo", e);
  }