Как разбирать строку без кавычек JSON

У меня есть строка JSON, где ни ключевые, ни значения не цитируются, и я хотел бы преобразовать ее в правильно отформатированный JSON.

{basic:{0:{index:0, license:t, nameSID:n, image:"img_left", descriptionSID:t, category:r}}

Есть ли библиотека Java, которая могла бы ее обработать? Я пробовал Jackson, но он не работает.

С уважением, Ян

Ответ 1

Вы можете использовать JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES с помощью Jackson, чтобы разрешить имена без кавычек:

JsonFactory factory = new JsonFactory();
factory.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
JsonParser jp = factory.createJsonParser(new FileInputStream("content.json"));

Ответ 2

Не уверен, что вам удалось написать собственный парсер или нет, но я это сделал.

https://github.com/ischumacher/rsjp

Вот пример использования с вашим примером JSON:

String str = "{basic:{0:{index:0, license:t, nameSID:n, image:\"img_left\", descriptionSID:t, category:r}}";
Map<String, Object> jso = Json.parseJSON(str);
System.out.println(jso);
System.out.println(Json.get(jso, "basic", "0", "image"));

Вот результат:

{
   basic: 
   {
      0: 
      {
         index: 0, 
         license: t, 
         nameSID: n, 
         image: img_left, 
         descriptionSID: t, 
         category: r
      }
   }
}

img_left

Ответ 3

Я рассмотрел вопрос о том, как можно настроить настройку Jackson для обработки некотируемых значений полей (по сравнению с именами полей). Несмотря на то, что я закончил писать хак вместо этого, я отправляю свою тротуарную дорожку для других. Мое шифрование кода было выполнено в Jackson 2.7.2.

Jackson Core поставляется с двумя конкретными реализациями интерфейса JsonParser:

  • ReaderBasedJsonParser, парсер для потоков символов (кодирование независимые)
  • UTF8StreamJsonParser, парсер, оптимизированный для байт UTF-8 Потоки

Код в этих двух классах является излишним, вероятно, по необходимости. Каждый класс имеет метод, который вызывается nextToken(), когда встречается неожиданный символ. ReaderBasedJsonParser называется _handleOddValue(), а UTF8StreamJsonParser - _handleUnexpectedValue(). Здесь можно найти такие вещи, как принятие значения "NaN" в качестве числового значения и использование одноцилинтных значений строк.

Мой план (прежде чем я пришел в себя и понял, что ужасный хак был достаточным для моих краткосрочных потребностей) заключался в подклассе одного из обоих этих парсеров и переопределении вышеприведенных методов для обработки некорректных строковых значений. Поскольку этот метод вызывается, когда входной поток находится в контексте значения поля (сразу после распознавания двоеточия), его следует читать вперед до тех пор, пока не встретится запятая или правая фигурная скобка и не подсчитайте все прочитанные до этой точки как строковое значение. Этот код сложно записать, так как он требует понимания стратегии буферизации Джексона, архитектуры парсера (текущий указатель на текущий буфер является переменной экземпляра) и т.д.

Чтобы сделать ObjectMapper, используйте этот настраиваемый парсер, необходимо подклассифицировать JsonFactory и переопределить метод _createParser() с помощью экземпляра, который его создает. Может потребоваться дополнительная работа, чтобы как обычный, так и UTF-8-парсер работать правильно, хотя это достаточно, чтобы принудительно использовать регулярный синтаксический анализатор, если производительность не вызывает беспокойства. Затем экземпляр этого пользовательского JsonFactory может быть передан в конструктор ObjectMapper.

Надеюсь, это поможет кому-то.