Разобрать вложенный JSON как необработанную строку - PullRequest
1 голос
/ 21 июня 2019

Я пишу лямбда-функцию, которая получает объект очереди SQS. 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. Я попытался проанализировать его как необработанное значение, например Как включить необработанный JSON в объект, используя Джексона? , но он продолжает жаловаться, что обнаружил, где он ожидал разделить запятыми объект.

Поскольку я не могу опубликовать необработанный 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;
}
}

Это то, что у меня есть сейчас. Я попытался изменить сообщение на строку, но это ничего не изменило.

1 Ответ

1 голос
/ 21 июня 2019

Основная проблема в том, что "Message":"{"uuid":"someUuid"}" не является допустимым json и, следовательно, Джексон не может разобрать эту часть. С точки зрения json значение "Message" равно "{" и, следовательно, следующее uuid вызывает ошибку.

Чтобы справиться с этим, вам нужно правильно экранировать вложенный json, чтобы он выглядел как любая другая строка для Джексона, т. Е. Вы хотели бы получить что-то вроде этого:

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

Здесь значение "Message" равно "{\"uuid\":\"someUuid\"}", и, таким образом, Джексон может взять эту строку и обработать ее далее (поместить в строку или удалить из нее и проанализировать).

Это означает, что вы не должны пытаться решить проблему на стороне синтаксического анализа, а на стороне генерации, то есть там, где создается тело запроса для HandleServiceRequest(...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...