SQSListener获取消息属性异常:@Header取到消息体而非指定属性值
解决Spring SQS监听中@Header获取消息属性失败,拿到消息体的问题
问题现象
使用Spring Cloud AWS的@SqsListener监听队列时,消息体MyEvent解析正常,但通过@Header("srcId")获取的不是SQS消息属性中的val1,而是整个消息体的JSON字符串。
问题原因
- 注解使用不当:通用的
@Header注解无法正确识别AWS SQS特有的消息属性映射,Spring Cloud AWS提供了专门的@MessageHeader注解用于处理队列消息头。 - Header解析器配置错误:手动初始化的
HeaderMethodArgumentResolver未传入正确的SqsHeaderMapper,导致无法解析SQS的消息属性,转而错误地将消息体当作Header值返回。
解决方案
步骤1:替换注解
将方法参数中的@Header替换为@MessageHeader,该注解是Spring Cloud AWS专为消息队列场景设计,能精准映射SQS的消息属性:
@SqsListener(value = "my_queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS) public void receive(MyEvent event, @MessageHeader("srcId") String srcId){ log.error("abc -> " + srcId); // ...业务逻辑 }
步骤2:修复QueueMessageHandlerFactory配置
调整参数解析器的初始化逻辑,传入正确的SQS头部映射器,或直接让Spring自动装配参数解析器:
方式一:手动配置正确的Header解析器
@Bean public QueueMessageHandlerFactory queueMessageHandlerFactory( final ObjectMapper mapper, final AmazonSQSAsync amazonSQSAsync){ final QueueMessageHandlerFactory factory = new QueueMessageHandlerFactory(); factory.setAmazonSqs(amazonSQSAsync); // 使用默认SQS头部映射器解析消息属性 SqsHeaderMapper headerMapper = new DefaultSqsHeaderMapper(); factory.setArgumentResolvers(Arrays.asList( new PayloadMethodArgumentResolver(myConverter(mapper)), new HeaderMethodArgumentResolver(headerMapper, null) )); return factory; }
方式二:简化配置,让Spring自动装配解析器
放弃手动指定参数解析器,仅设置自定义消息转换器,Spring会自动加载包括消息头解析器在内的默认组件:
@Bean public QueueMessageHandlerFactory queueMessageHandlerFactory( final ObjectMapper mapper, final AmazonSQSAsync amazonSQSAsync){ final QueueMessageHandlerFactory factory = new QueueMessageHandlerFactory(); factory.setAmazonSqs(amazonSQSAsync); MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setObjectMapper(mapper); factory.setMessageConverters(Collections.singletonList(converter)); return factory; }
验证
重新执行AWS CLI发送消息的命令后,日志将输出预期结果:abc -> val1
内容的提问来源于stack exchange,提问作者Laodao
相关产品推荐
相关产品推荐

