SQS推送JSONObject负载出现{empty:true}问题排查
问题分析与解决方案
核心原因
QueueMessagingTemplate.convertAndSend 默认依赖Spring的消息转换器体系(通常是 MappingJackson2MessageConverter)序列化消息体。而你使用的 JSONObject(不管是org.json还是FastJSON实现)本质上不是标准POJO:
- 它内部用哈希表存储键值对,没有暴露对应getter/setter方法
- Jackson默认序列化逻辑无法识别其内部存储的属性,只能读取到内置的
empty标识属性,最终输出{empty:true}
自定义Java对象是标准POJO,Jackson可通过反射识别字段正常序列化;调用jsonObject.toString()时,转换器会将其视为普通字符串直接发送,自然能得到正确JSON内容。
可行解决方案
1. 直接用JSONObject.toString()发送(最简单)
这是你已验证有效的方式,直接将JSON对象转为字符串传入convertAndSend,避免序列化问题:
queueMessagingTemplate.convertAndSend(queueName, jsonObject.toString());
2. 配置自定义消息转换器支持JSONObject
若希望直接传入JSONObject也能正常序列化,可自定义MappingJackson2MessageConverter并配置Jackson支持JSONObject:
@Bean public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSqs) { QueueMessagingTemplate template = new QueueMessagingTemplate(amazonSqs); MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); // 注册Jackson处理org.json.JSONObject的模块,需引入jackson-datatype-json-org依赖 objectMapper.registerModule(new JsonOrgModule()); converter.setObjectMapper(objectMapper); converter.setSerializedPayloadClass(String.class); template.setMessageConverter(converter); return template; }
注:如果用FastJSON的JSONObject,需替换为对应FastJSON序列化模块配置。
3. 回归使用自定义POJO(Spring推荐方式)
Spring消息转换器的设计初衷就是简化POJO与JSON的转换,直接传入自定义Java对象,Spring会自动序列化为JSON字符串,避免手动处理JSONObject的麻烦:
// 自定义消息POJO public class TaskMessage { private String payload; private String taskId; // 构造方法、getter、setter } // 发送时直接传对象 TaskMessage message = new TaskMessage(); message.setPayload("test content"); message.setTaskId("task-001"); queueMessagingTemplate.convertAndSend(queueName, message);
内容的提问来源于stack exchange,提问作者Gayathry S
相关产品推荐
相关产品推荐

