将 SqsListener 与 SNS 和 SQS 结合使用
Using SqsListener with SNS and SQS
我正在使用来自 AWS 的简单队列服务 (SQS) 的 spring-cloud-aws's SqsListener to receive AWS SNS HTTP Notifications in JSON Format。
这是侦听器的代码:
@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final MyObject obj) throws Exception {
// ...
}
上面链接的文档只是关于向队列发送和读取普通序列化对象,我认为接收 SNS 消息应该是开箱即用的。但我最终收到转换错误:
10:45:51.480 [simpleMessageListenerContainer-2] ERROR
o.s.c.a.m.l.SimpleMessageListenerContainer - Exception encountered
while processing message.
org.springframework.messaging.MessagingException: An exception
occurred while invoking the handler method; nested exception is
org.springframework.messaging.converter.MessageConversionException: No
converter found to convert to class com.myproject.model.MyObject,
message=GenericMessage
我还尝试创建一个包装器对象,它看起来像上面链接的预期 SNS Json 格式,但我总是遇到同样的异常。唯一有效的类型是签名中的字符串。 SNS不应该自动转换吗?
是的,它应该。它确实如此。
为了在反序列化时调用正确的 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 {
// ...
}
这样,您的 SNS 的 Message
部分将被提取并转换为 MyObject
。
这在没有 @NotificationMessage
的情况下也有效。这样您就不需要发送 "Type" 和 "Message" 部分,这是使用此注释所必需的。
首先创建一个具有所需属性的 class。
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"}
POJO 构造函数中的 @JsonProperty("MyTask")
注释可以是可选的,具体取决于您的 spring 版本以及您的属性是否与 Json 字符串中的名称相同。例如,如果您的属性名为 task
并且您的 Json 字符串为 {"task":"My task"}
.
,则没有必要
我正在使用来自 AWS 的简单队列服务 (SQS) 的 spring-cloud-aws's SqsListener to receive AWS SNS HTTP Notifications in JSON Format。
这是侦听器的代码:
@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final MyObject obj) throws Exception {
// ...
}
上面链接的文档只是关于向队列发送和读取普通序列化对象,我认为接收 SNS 消息应该是开箱即用的。但我最终收到转换错误:
10:45:51.480 [simpleMessageListenerContainer-2] ERROR o.s.c.a.m.l.SimpleMessageListenerContainer - Exception encountered while processing message. org.springframework.messaging.MessagingException: An exception occurred while invoking the handler method; nested exception is org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class com.myproject.model.MyObject, message=GenericMessage
我还尝试创建一个包装器对象,它看起来像上面链接的预期 SNS Json 格式,但我总是遇到同样的异常。唯一有效的类型是签名中的字符串。 SNS不应该自动转换吗?
是的,它应该。它确实如此。
为了在反序列化时调用正确的 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 {
// ...
}
这样,您的 SNS 的 Message
部分将被提取并转换为 MyObject
。
这在没有 @NotificationMessage
的情况下也有效。这样您就不需要发送 "Type" 和 "Message" 部分,这是使用此注释所必需的。
首先创建一个具有所需属性的 class。
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"}
POJO 构造函数中的 @JsonProperty("MyTask")
注释可以是可选的,具体取决于您的 spring 版本以及您的属性是否与 Json 字符串中的名称相同。例如,如果您的属性名为 task
并且您的 Json 字符串为 {"task":"My task"}
.