ALLOW_UNQUOTED_FIELD_NAMES в библиотеке JONON Jackon
Я использую библиотеку jackson для сериализации/десериализации в/из JSON. Мне нужно, чтобы этот JSON имел минимальный размер, поэтому я включил функцию ALLOW_UNQUOTED_FIELD_NAMES, чтобы устранить все кавычки. Я знаю, что удаление котировок не является стандартным json, но сделать json small является жестким требованием проекта. Сгенерированный json работает, но когда я пытаюсь прочитать значение json, я получаю исключение:
org.codehaus.jackson.JsonParseException: Неожиданный символ ('9' (код 57)): ожидало либо действительного имени символ (для некотируемого имени) или двойная кавычка (для цитирования) для начала имя поля в [Источник: [email protected]; линия 1, столбец: 3]
Исключение выше, когда я прочитал этот json:
{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1}
Как я его читаю:
Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {});
и для сопоставления объектов я использую как для чтения, так и для записи значений:
private static final ObjectMapper om = new ObjectMapper();
static {
om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true);
om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
}
Я использую версию 1.6.3 Jackson в проектах отправителя и получателя. Необходимая версия для этой функции - 1.2+, поэтому я подумал, что, возможно, я не использовал эту версию, но мой ресивер - это приложение Spring, и я проверил, что библиотека, установленная в папке libs, составляет 1.6.3.
Что я могу делать неправильно? Возможно, эта функция не может использоваться с картами.
У меня есть другой вопрос. Пока я просто отправляю карту, где ключ является только значением uuid, а значение - числом. У меня возникли проблемы, если я отправлю значение со специальными символами с функцией ALLOW_UNQUOTED_FIELD_NAMES? Выйдет ли джексон из этих символов?
Спасибо.
Ответы
Ответ 1
Похоже, что Джексон с QUOTE_FIELD_NAMES
в некоторых случаях производит такой вывод, что он не может читать себя даже с ALLOW_UNQUOTED_FIELD_NAMES
on. Возможно, вам понадобится реализовать пользовательский JsonParser
для нестандартного анализа ввода.
Проблема в том, что вы генерируете нестандартный JSON, и нет никаких гарантий, что клиент будет обращаться с ним должным образом. Однако, если вы не раскрываете его за пределами своих приложений и не заботитесь о размере, вы можете разобрать/генерировать двоичный формат, например Jackson Smile. См. http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).
Ответ 2
Хорошо, ответ Pingw33n довольно верный, я думаю. Итак: да, вы можете использовать эту функцию; но он довольно эвристичен - поскольку нет спецификации того, как работать с неупомянутыми именами (в конце концов, JSON разрешает любые и все символы для имен!); или, что, если какой-либо механизм эвакуации должен использоваться, он все догадывается, что должно быть написано или принято.
В этом конкретном случае это, вероятно, символ "-", который вызывает проблему. Это не правовая часть имени Javascript, которое является приближением, которое использует Джексон.
Одним из возможных решений для Джексона было бы избежать таких символов в именах свойств (я не помню, как это делается в настоящее время, если указаны какие-либо имена). Если вы можете найти простой тестовый пример, вы можете подать заявку на участие в Jira для Jackson Jira, чтобы ускорить добавление (и обеспечить парсер может отменить обычную версию обратной косой черты).
Ответ 3
Я считаю, что проблема связана с Javascript sintax, а не с Jackson и JSON.
В Javascript имя - это письмо, которое необязательно следует одной или нескольким буквам, цифрам или подрамкам, поэтому 90110a2e-febd-470f-afa4-cf7e890d31b9 не является юридическим именем Javascript.
Котировки вокруг имени свойства являются необязательными, если имя будет легальным именем JavaScript, а не зарезервированным словом. Таким образом, кавычки требуются вокруг "first-name", но необязательны вокруг first_name.
Кстати, если вы так обеспокоены размером JSON, почему бы вам не gzip его?