简体   繁体   English

将SqsListener与SNS和SQS一起使用

[英]Using SqsListener with SNS and SQS

I'm using spring-cloud-aws 's SqsListener to receive AWS SNS HTTP Notifications in JSON Format from AWS's Simple Queue Service (SQS). 我正在使用spring-cloud-awsSqsListener从AWS的简单队列服务(SQS)接收JSON格式的 AWS SNS HTTP通知。

This is the code for the listener: 这是监听器的代码:

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

The documentation linked above is only about sending and reading plain serialized objects to the Queue and I thought that receiving SNS messages is expected to work out of the box. 上面链接的文档只是关于向队列发送和读取普通的序列化对象,我认为接收SNS消息应该是开箱即用的。 But I end up receiving conversion errors: 但我最终收到转换错误:

10:45:51.480 [simpleMessageListenerContainer-2] ERROR oscamlSimpleMessageListenerContainer - Exception encountered while processing message. 10:45:51.480 [simpleMessageListenerContainer-2] ERROR oscamlSimpleMessageListenerContainer - 处理消息时遇到异常。 org.springframework.messaging.MessagingException: An exception occurred while invoking the handler method; org.springframework.messaging.MessagingException:调用处理程序方法时发生异常; nested exception is org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class com.myproject.model.MyObject, message=GenericMessage 嵌套异常是org.springframework.messaging.converter.MessageConversionException:找不到转换为com.myproject.model.MyObject类的转换器,message = GenericMessage

I also tried creating a wrapper object that looks like the expected SNS Json Format linked above, but I keep getting the same exception. 我也尝试创建一个看起来像上面链接的预期SNS Json格式的包装器对象,但我一直得到相同的异常。 The only type that works is a String in the signature. 唯一有效的类型是签名中的String。 Shouldn't the SNS be converted automatically? 不应该自动转换SNS吗?

Yes it should. 是的,它应该。 And it does actually. 它实际上确实如此。

In order to have the correct HandlerMethodArgumentResolver invoked (in this case NotificationMessageArgumentResolver ) on deserialization, which in turn invokes the correct converter NotificationRequestConverter you simply need to add the annotation org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage to your method signature. 为了在反序列化时调用正确的HandlerMethodArgumentResolver (在本例中为NotificationMessageArgumentResolver ),反过来调用正确的转换器NotificationRequestConverter您只需要在方法中添加注释org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage签名。 Eg 例如

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

This way the Message part of your SNS gets extracted and converted to MyObject . 这样,SNS的Message部分将被提取并转换为MyObject

This works without the @NotificationMessage as well. 这也可以在没有@NotificationMessage情况下工作。 This way you don't need to send the "Type" and "Message" part, that is required to work with this annotation. 这样您就不需要发送使用此注释所需的“类型”和“消息”部分。

First create a class with the needed attributes. 首先创建一个具有所需属性的类。

public class SqsMessage {

   private String myTask;

   public SqsMessage() {
   }

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

   //Getter + Setter 
}

Next set up the Listener 接下来设置监听器

@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());
}

Now you can send a JSON like 现在您可以发送类似的JSON

{"MyTask":"My task"}

The @JsonProperty("MyTask") annoation in the POJO's constructor can be optional, depending on your spring version and if your attribute has the same name as in the Json string. POJO构造函数中的@JsonProperty("MyTask") annoation可以是可选的,具体取决于您的spring版本以及您的属性是否与Json字符串中的名称相同。 It's not necessary for example, if your attribute is called task and your Json string is {"task":"My task"} . 例如,如果你的属性被称为task而你的Json字符串是{"task":"My task"} ,则没有必要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM