我正在编写接收SQS队列对象的Lambda函数。 SQS将json对象作为字符串值发送到SQS。
当我在Lambda中收到请求时,AWS将其包装到新的JSON中,并且由于json是字符串值,因此它变为无效的json。
(示例) json看起来像:
{"uuid ":"someuuid"}
我们将其作为字符串发送到SQS。 然后,AWS将其包装为以下内容:
{
"Records": [
{
"messageId": "somemesasgeid",
"receiptHandle": "MessageReceiptHandle",
"body": {
"Message":"{"uuid":"someUuid"}"
},
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "sometimestamp",
"SenderId": "someid",
"ApproximateFirstReceiveTimestamp": "sometimestamp"
},
"messageAttributes": {},
"md5OfBody": "somebody",
"eventSource": "aws:sqs",
"eventSourceARN": "someARN",
"awsRegion": "eu-west-1"
}
]
}
现在body.Message无效的Json。我尝试将其解析为像How can I include raw JSON in an object using Jackson?这样的原始值,但它一直抱怨它在期望逗号分隔对象的位置找到了u。
由于我无法将原始json发布到SQS并必须对其进行字符串化,因此如何将其解析为可以获取json消息的对象?
我尝试创建一个pojo并尝试了上面的链接,但是杰克逊一直抱怨message变量。
---更新代码---
private Response HandleServiceRequest(Map<String, Object> input) {
List<String> records = (List<String>) input.get("Records");
for(String r : records) {
SqsMessage m = objectMapper.readValue(r, SqsMessage.class);
}
}
public class SqsMessage {
// all other values
SqsBody body;
// getters/setters
}
public class SqsBody {
// all other values
@JsonProperty("Message")
private Object message;
// getters/setters
@JsonRawValue
public String getMessage() {
message == null ? null : message.toString();
}
public void setMessage(Object message){
this.message = message;
}
}
这就是我现在所拥有的。我尝试将消息更改为String,但没有任何改变。
答案 0 :(得分:1)
基本问题是"Message":"{"uuid":"someUuid"}"
是无效的json,因此Jackson无法解析此部分。从json的角度来看,"Message"
的值为"{"
,因此后面的uuid
会导致错误。
要处理此问题,您需要正确地转义嵌套的json,以便它看起来像Jackson的任何其他字符串一样,即,您想要得到这样的东西:
"Message":"{\"uuid\":\"someUuid\"}"
此处"Message"
的值为"{\"uuid\":\"someUuid\"}"
,因此Jackson可以接收该字符串并进一步处理(将其放入字符串或取消转义并解析)。
这意味着您不应该尝试在解析方面解决问题,而应该在生成方面,即在创建HandleServiceRequest(...)
的请求正文的地方解决问题。