将嵌套的json解析为原始字符串

时间:2019-06-21 09:44:13

标签: java json jackson

我正在编写接收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,但没有任何改变。

1 个答案:

答案 0 :(得分:1)

基本问题是"Message":"{"uuid":"someUuid"}"是无效的json,因此Jackson无法解析此部分。从json的角度来看,"Message"的值为"{",因此后面的uuid会导致错误。

要处理此问题,您需要正确地转义嵌套的json,以便它看起来像Jackson的任何其他字符串一样,即,您想要得到这样的东西:

"Message":"{\"uuid\":\"someUuid\"}"

此处"Message"的值为"{\"uuid\":\"someUuid\"}",因此Jackson可以接收该字符串并进一步处理(将其放入字符串或取消转义并解析)。

这意味着您不应该尝试在解析方面解决问题,而应该在生成方面,即在创建HandleServiceRequest(...)的请求正文的地方解决问题。