При интеграции 1С с MongoDB с использованием RESTHeart разработчики часто сталкиваются с ситуацией, когда попытка записать документ методом PUT или POST завершается ошибкой с кодом HTTP 406 Not Acceptable. Проанализируем, почему возникает эта ошибка, где скрывается проблема при формировании JSON-запроса и как правильно передавать данные без сбоев.
В тексте ответа от сервера RESTHeart при ошибке 406 обычно содержатся следующие детали:
{"_exceptions":[{"exception":"org.bson.json.JsonParseException","exception message":"Invalid JSON input. Position: 6. Character: '\ufeff'."}],"http status code":406,"http status description":"Not Acceptable","message":"Invalid JSON"}
Разберем, что означает данный ответ. Символ \ufeff — это маркер последовательности байтов (Byte Order Mark, или BOM). Когда платформа 1С формирует тело запроса с помощью метода УстановитьТелоИзСтроки() без дополнительных параметров, в начало передаваемого UTF-8 потока автоматически вставляется этот служебный символ.
Парсер BSON/JSON на стороне Java-сервиса RESTHeart не ожидает посторонних символов перед открывающей фигурной скобкой {. Получив маркер BOM, сервер отклоняет пакет как некорректный JSON (Invalid JSON) и возвращает статус 406 Not Acceptable.
Рассмотрим основной способ решения проблемы на платформе 1С:Предприятие 8.3. Для того чтобы метод УстановитьТелоИзСтроки() не добавлял маркер BOM в начало текстового содержимого, необходимо явно указать третий параметр — ИспользованиеByteOrderMark.НеИспользовать.
Разберем по шагам правильный алгоритм отправки JSON-документа:
Соответствие или Структура.ЗаписьJSON.Content-Type и Accept.Посмотрим на пример итогового кода 1С:
Соединение = Новый HTTPСоединение("localhost", 8080, "Логин", "Пароль",, 60);
// Заполняем заголовки запроса
ЗаголовокЗапроса = Новый Соответствие;
ЗаголовокЗапроса.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовокЗапроса.Вставить("Accept", "application/json");
ЗаголовокЗапроса.Вставить("Authorization", "Basic " + ХэшАвторизации("Логин", "Пароль"));
// Готовим данные для отправки
ИмяФайла = "C:\Data\ObmenMongo\dsfs.png";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяФайла);
СтруктураДокумента = Новый Соответствие;
СтруктураДокумента.Вставить("Base", "1CBase");
СтруктураДокумента.Вставить("Date", ТекущаяДата());
СтруктураДокумента.Вставить("File", Base64Строка(ДвоичныеДанныеФайла));
СтруктураДокумента.Вставить("desc", ИмяФайла);
// Настраиваем параметры записи JSON без переносов строк
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
ЗаписатьJSON(ЗаписьJSON, СтруктураДокумента);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Создаем запрос и отключаем BOM
ИмяРесурса = "/FileBaseDB/FileTable/" + Документ.Ссылка.УникальныйИдентификатор() + "?id_type=STRING";
HTTPЗапрос = Новый HTTPЗапрос(ИмяРесурса, ЗаголовокЗапроса);
// ВАЖНО: передаем ИспользованиеByteOrderMark.НеИспользовать
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
ИмяФайлаОтвета = ПолучитьИмяВременногоФайла("txt");
Ответ = Соединение.ВызватьHTTPМетод("PUT", HTTPЗапрос, ИмяФайлаОтвета);
Если разработка ведется на более старых версиях платформы 1С, где метод УстановитьТелоИзСтроки() не поддерживает параметры управления BOM, проанализируем альтернативный вариант. Данные можно перевести в двоичный формат с явным отключением BOM с помощью функции ПолучитьДвоичныеДанныеИзСтроки() и затем передать их через УстановитьТелоИзДвоичныхДанных().
Рассмотрим пример реализации:
// Формируем двоичные данные из строки без BOM
ДвоичноеТело = ПолучитьДвоичныеДанныеИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
HTTPЗапрос = Новый HTTPЗапрос(ИмяРесурса, ЗаголовокЗапроса);
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичноеТело);
Ответ = Соединение.ВызватьHTTPМетод("PUT", HTTPЗапрос, ИмяФайлаОтвета);
Проанализируем архитектурную особенность хранения файлов в MongoDB. Кодирование файлов в Base64 для передачи внутри стандартного JSON-документа увеличивает размер отправляемых данных примерно на 33% и ограничен максимальным размером BSON-документа (16 МБ).
Для эффективной работы с файлами в RESTHeart встроен модуль GridFS. Вместо упаковки файла в Base64 рекомендуется использовать специальные эндпоинты GridFS, передавая двоичное содержимое файла напрямую в теле запроса методом PUT или POST. Это снимает ограничения по размеру и полностью исключает ошибки, связанные с текстовым парсингом JSON и кодировками.