web-dev-qa-db-ja.com

Spring Cloud @SqsListener MessageConversionException:GenericMessageの[Java.lang.String]から変換できません

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ライブラリを持っているので、PayloadArgumentResolverMappingJackson2MessageConverterを使用してメッセージペイロードをデシリアライズしようとしています。ただし、SQSメッセージにはcontentTypeヘッダーがなく、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ヘッダーを設定する方法がわかりません-何か不足していますか?

Spring Cloud QueueMessageHandlerstrictContentTypeMatchを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

11
Joe Stepowski

同じ問題に遭遇し、メッセージを生成した人に応じて、2つの方法のいずれかで質問に答えます

  • はい、メッセージにcontentTypeを設定することが可能です。生成されるメッセージを制御する場合は、これが推奨されます。 AWSコンソールでは、メッセージを手動で送信するときに、「メッセージ属性」のタブがあります。名前contentTypeと値application/jsonの属性を追加します。 AWS SDK呼び出しでは、アプリケーションコードから同じことができるはずです。

  • S3イベントのように、コンテンツが指定されていないコンテンツタイプなしでAWSが生成するメッセージの場合、実際にはstrictContentMatchをfalseに設定する必要があります。これはここに記載されています: http://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.0.RELEASE/multi/multi__messaging.html#_sumption_aws_event_messages_with_Amazon_sqs

「mime-typeヘッダーなし」と書かれているため、ドキュメントはわかりにくいですが、ヘッダーの実際の名前はcontentTypeです。

8
wrschneider