12

我正在使用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 {
// ...
}

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

10:45:51.480 [simpleMessageListenerContainer-2] 错误 oscamlSimpleMessageListenerContainer - 处理消息时遇到异常。org.springframework.messaging.MessagingException:调用handler方法时发生异常;嵌套异常是 org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class com.myproject.model.MyObject, message=GenericMessage

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

4

2 回答 2

8

是的,它应该。它确实如此。

为了在反序列化时正确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 {
// ...
}

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

于 2016-04-11T08:54:10.117 回答
3

这在没有 the 的情况下@NotificationMessage也有效。这样您就不需要发送使用此注释所需的“类型”和“消息”部分。

首先创建一个具有所需属性的类。

public class SqsMessage {

   private String myTask;

   public SqsMessage() {
   }

   public SqsMessage(@JsonProperty("MyTask") String myTask ) {
       this.myTask = myTask ;
   }

   //Getter + Setter 
}

接下来设置监听器

@SqsListener(value = {"MyQueue"}, deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void receiveMessage(SqsMessage payload, @Headers Map<String, Object> header) {
   logger.info("Got message with task: " + payload.getTask() 
    + " with custom attribute " + header.get("CustomAttribute").toString());
}

现在你可以发送一个 JSON 像

{"MyTask":"My task"}

@JsonProperty("MyTask")POJO 构造函数中的注释可以是可选的,具体取决于您的 spring 版本以及您的属性是否与 Json 字符串中的名称相同。例如,如果您的属性被调用task并且您的 Json 字符串为{"task":"My task"}.

于 2019-03-21T15:19:19.333 回答