【问题标题】:Parse nested json as raw string将嵌套的 json 解析为原始字符串
【发布时间】:2019-11-04 03:40:40
【问题描述】:

我正在编写一个接收 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 并尝试上面的链接,但杰克逊一直抱怨消息变量。

--- 用代码更新---

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;
}
}

这就是我现在所拥有的。我尝试将消息更改为字符串,但这并没有改变任何内容。

【问题讨论】:

  • 您可以尝试将嵌套的 json 视为字符串而不是 json 或 pojo 吗?这样它应该被转义并导致类似"Message":"{\"uuid\":\"someUuid\"}"
  • 我试过了。字符串甚至对象。杰克逊仍然会尝试解析它。不过,我可以尝试在将 json 发送到 SQS 之前对其进行转义.. 试试这个
  • Jackson 不应该尝试解析字符串值,除非你告诉它 "Message" 是别的东西。您能否提供更多信息,例如minimal reproducible example?
  • @Thomas 这就是我现在所拥有的。我尝试将消息更改为字符串,但这对我没有任何影响。
  • 好吧,您已经发布了您尝试解析 json 的方式,但我要了解的是您如何生成 它? "Message":"{"uuid":"someUuid"}" 不是有效的 json,所以 Jackson 在任何情况下都会遇到解析问题。您需要在生成时将嵌套的 json 转义,即将其转换为我在第一条评论中建议的形式 - 只有正确转义字符串内容,Jackson 才能读取整个字符串。

标签: java json jackson


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-21
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2013-12-25
    相关资源
    最近更新 更多