
aws sqs 要求消息体必须是合法的 json 字符串,而 `jsonobject` 是 java 对象,并非字符串;直接传递 `jsonobject` 会导致序列化异常或空内容(如 `{empty:true}`),需显式调用 `.tostring()` 转为标准 json 字符串后再发送。
在使用 Spring Cloud AWS 的 QueueMessagingTemplate.convertAndSend() 方法向 Amazon SQS 发送消息时,底层会依赖 Jackson 或默认的 MessageConverter 对传入对象进行序列化。该方法对不同类型的输入行为如下:
- ✅ String 类型:直接作为消息体发送,无需额外序列化;
- ✅ 自定义 Java Bean(如 TaskMessage):由 Jackson 自动序列化为标准 JSON 字符串(前提是字段可访问、无循环引用等);
- ❌ org.json.JSONObject 类型:它不是标准 POJO,也不实现 Serializable 的语义化序列化契约;Spring 默认的 MappingJackson2MessageConverter 无法正确识别其结构,可能触发其内部 empty 标志逻辑(尤其在老版本 org.json:json 中),最终导致消息体被错误地序列化为 { "empty": true }。
正确做法:始终发送 JSON 字符串
应确保传入 convertAndSend() 的参数是 String 类型,且内容为格式良好的 JSON:
public String toJson() throws JSONException {
JSONObject json = new JSONObject();
json.put("payload", this.payload);
json.put("id", this.taskId);
return json.toString(); // ← 关键:转为字符串!
}然后调用:
queueMessagingTemplate.convertAndSend(queueUrl, task.toJson());
补充说明与最佳实践
⚠️ 不要依赖 JSONObject 对象本身作为消息载荷 —— 它是工具类,不是数据载体;
-
✅ 推荐统一使用 Jackson(ObjectMapper)处理序列化,更可控、兼容性更好:
private static final ObjectMapper mapper = new ObjectMapper(); public String toJson() throws JsonProcessingException { return mapper.writeValueAsString(Map.of( "payload", this.payload, "id", this.taskId )); } ? 若必须使用 org.json,请确认依赖版本(建议 ≥ 20230227),并避免嵌套 JSONObject/JSONArray 中含非标准类型(如 LocalDateTime),否则 toString() 可能抛异常;
? 测试建议:发送前打印 json.toString() 结果,验证是否输出预期 JSON(如 {"payload":"data","id":"123"}),而非 {} 或 {empty:true}。
总之,SQS 消息体本质是纯文本协议,一切需归结为合法 JSON 字符串——这是集成中最易忽视却最关键的一环。










