有没有办法向 SqsListener 添加 ErrorHandler 或 ExceptionHandler?

Is there a way to add a ErrorHandler or ExceptionHandler to SqsListener?

我有一个 SqsListener,它使用带有消息转换器的自定义 QueueMessageHandlerFactory 从 JSON 到 POJO 并返回。如果出于某种原因侦听器方法无法解析消息中的 JSON 正文,它将抛出 org.springframework.messaging.converter.MessageConversionException。我想捕获这个异常并正确记录它。我知道 JMS 侦听器允许您添加自定义 ErrorHandler 作为工厂定义的一部分。

是否有类似的方法来定义自定义 ErrorHandler 以使用 Spring 的 SqsListener 捕获此异常并记录它?

谢谢!

  @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

没关系,似乎我需要做的就是向我的自定义处理程序添加 @MessageExceptionHandler 注释:

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