将SqsListener与SNS和SQS结合使用

msp*_*msp 8 java spring amazon-web-services spring-cloud spring-cloud-aws

我正在使用spring-cloud-awsSqsListener从AWS的简单队列服务(SQS)接收JSON格式的 AWS SNS HTTP通知。

这是侦听器的代码:

@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final MyObject obj) throws Exception {
// ...
}
Run Code Online (Sandbox Code Playgroud)

上面链接的文档仅关于向队列发送和读取普通序列化对象,我认为接收SNS消息应该可以立即使用。但是我最终收到转换错误:

10:45:51.480 [simpleMessageListenerContainer-2]错误oscamlSimpleMessageListenerContainer-处理消息时遇到异常。org.springframework.messaging.MessagingException:调用处理程序方法时发生异常;嵌套的异常是org.springframework.messaging.converter.MessageConversionException:未找到可转换为com.myproject.model.MyObject类的转换器,message = GenericMessage

我还尝试创建一个包装对象,该包装对象看起来像上面链接的预期的SNS Json格式,但是我一直收到相同的异常。唯一有效的类型是签名中的字符串。SNS是否应该自动转换?

msp*_*msp 6

是的,应该。实际上是这样。

为了在反序列化上HandlerMethodArgumentResolver调用正确的方法(在本例中为NotificationMessageArgumentResolver),反序列化又调用正确的转换器,NotificationRequestConverter您只需要org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage在方法签名中添加注释即可。例如

@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final @NotificationMessage MyObject obj) throws Exception {
// ...
}
Run Code Online (Sandbox Code Playgroud)

这样Message,您的SNS部分就被提取并转换为MyObject

  • 添加到这个答案,对我来说,简单地添加 @NotificationMessage 注释并没有帮助,因为我用自己的 ArgumentResolver 覆盖了 QueueMessageHandlerFactory。对于许多人来说都是这种情况,因为这是定制 Jackson 映射器所必需的。在这种情况下,必须更改解析器:从“factory.setArgumentResolvers(List.of(new PayloadArgumentResolver(jacksonMessageConverter)));”更改为“factory.setArgumentResolvers(List.of(new NotificationMessageArgumentResolver(jacksonMessageConverter)));” (4认同)