java - Spring Cloud @SqsListener MessageConversionException : Cannot convert from [java. lang.String] for GenericMessage

标签 java spring-cloud amazon-sqs

当我尝试使用 SQS 消息时,我看到以下异常:

org.springframework.messaging.converter.MessageConversionException: 

Cannot convert from [java.lang.String] to [com.example.demo.Foo] for GenericMessage [payload={}, headers={LogicalResourceId=my-queue, ApproximateReceiveCount=1, SentTimestamp=1529021258825, ReceiptHandle=xxxx, Visibility=org.springframework.cloud.aws.messaging.listener.QueueMessageVisibility@47ce6922, SenderId=xxxx, lookupDestination=my-queue, ApproximateFirstReceiveTimestamp=1529021264456, MessageId=xxxx}]
    at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144)
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:515)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:473)
    at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:409)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.executeMessage(SimpleMessageListenerContainer.java:205)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.run(SimpleMessageListenerContainer.java:342)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$SignalExecutingRunnable.run(SimpleMessageListenerContainer.java:397)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Spring Boot 代码如下:
@Configuration
@EnableSqs
public class AmazonSqsConfiguration {

    @Bean
    public AmazonSQS amazonSQSAsync() {
        return AmazonSQSAsyncClientBuilder.standard()
            .withRegion(Regions.US_WEST_2)
            .build();
    }
}

@Service
public class MyService {

    // Throws MessageConversionException
    @SqsListener("my-queue")
    public void listen(Foo payload) {

    }

    // Works fine
    @SqsListener("my-queue")
    public void listen(String payload) {

    }
}

我正在使用 org.springframework.cloud:spring-cloud-aws-messaging:2.0.0.RC2
我的类路径上确实有 Jackson 2 库,因此 PayloadArgumentResolver 试图使用 MappingJackson2MessageConverter 反序列化我的消息有效负载。但是,由于 SQS 消息缺少 contentType header 并且 strictContentTypeMatch 设置为 true,因此 canConvertFrom 返回 false。

https://github.com/spring-projects/spring-framework/blob/f5e8f4983f7653169f3da8a3287499fce93cadd4/spring-messaging/src/main/java/org/springframework/messaging/converter/AbstractMessageConverter.java#L237

我不知道如何为 SQS 消息设置 contentType header - 我是否遗漏了什么?

Spring Cloud QueueMessageHandler 是否应该将 strictContentTypeMatch 设置为 true?

https://github.com/spring-cloud/spring-cloud-aws/blob/6a7c3c31709d4239131b27936de29385df414d41/spring-cloud-aws-messaging/src/main/java/org/springframework/cloud/aws/messaging/listener/QueueMessageHandler.java#L217

最佳答案

遇到了同样的问题,我会根据谁生成消息来回答以下两种方式之一

  • 是的,可以设置 contentType在消息上,如果您控制正在生成的消息,则这是首选。在 AWS 控制台中,当您手动发送消息时,有一个“消息属性”选项卡。您将添加一个名为 contentType 的属性。和值(value) application/json . AWS SDK 调用应该允许您从应用程序代码中执行相同的操作。
  • 对于 AWS 在没有指定内容类型的情况下生成的消息,例如 S3 事件,您实际上需要设置 strictContentMatch为假。这是记录在这里:
    http://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.0.RELEASE/multi/multi__messaging.html#_consuming_aws_event_messages_with_amazon_sqs

  • 该文档令人困惑,因为它说“没有 mime 类型的标题”,但标题的实际名称是 contentType ,就像你发现自己一样。

    关于java - Spring Cloud @SqsListener MessageConversionException : Cannot convert from [java. lang.String] for GenericMessage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50867684/

    相关文章:

    java - 如何每隔 n 秒更改 imageview 中的图像

    amazon-web-services - 为什么从 SQS 调用时 Lambda 会受到限制?

    amazon-dynamodb - 使用 SQS 或 DynamoDB 控制订单状态

    java - 如何生成具有非重复数字的二维数组表?

    java - 我们可以使用 Java 在 openLDAP 中为域组件条目创建子上下文吗?

    java - Spring Cloud微服务,与其他微服务一起使用受密码保护的微服务

    java - "FF4J"(翻转)不适用于 "Hystrix"

    python - boto库如何读取飞行状态消息并删除

    java - 我如何将 JTextArea 添加到此代码中?

    spring - 如何删除 Spring Cloud Config Server 缓存