Прикручивая очередную интеграцию, понадобилось мне значит отправить на веб-сервис сайта POST запрос с остатками товаров. Остатки товаров были аккуратно упакованы в JSON. В версиях платформы выше 8.3.6 делается очень просто. Задача вроде как и тривиальная, но все же вызвала некоторые сложности. \
- Формирование валидного JSON из результата запроса.
2. Отправка сформированного запроса на сайта
Итак начнем по порядку.
Формирование JSON из Результата запроса
Ниже приведу код и добавлю некоторые комментарии для того чтобы было понятно. Вначале мы переводим Результат Запроса в ТаблицуЗначений (ТЗ) , затем ТЗ в Массив Структур. И только затем полученный массив сериализуем в JSON. В общем ничего сложного, код предельно простой.
Функция СформироватьJSON(ИдАптеки)
Если НЕ ЗначениеЗаполнено(ИдАптеки) Тогда
ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Ошибка,,,"Не указан ИД Аптеки",);
Возврат Неопределено;
КонецЕсли;
//Начинаем формирование прайса, сначала формируем остатки
ЗаписьЖурналаРегистрации(ИмяСобытияЖР,УровеньЖурналаРегистрации.Информация,,,"Выполнение запроса остатков...");
Рез = ВыполнитьЗапросОстатков(); // Тут у нас будет ТЗ значений с результатами запроса
КоличествоЗаписей = Рез.Количество();
ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Информация, , , "Запрос остатков выполнен. Количество записей: " + КоличествоЗаписей);
Если КоличествоЗаписей = 0 Тогда
Возврат Неопределено;
КонецЕсли;
// файл будем создавать в определенном каталоге на сервере,
// Если файл уже имеется то удалим его
Попытка
УдалитьФайлы("D:\temp\","pills.json");
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Запись = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( ,Символы.Таб);
Запись.ОткрытьФайл("D:\temp\pills.json",,,ПараметрыЗаписиJSON);
НастройкиСериализации = Новый НастройкиСериализацииJSON;
НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
Данные = Новый Структура;
Данные.Вставить("pharmacyCode", ИдАптеки);
Данные.Вставить("pills", ТабЗначВМассив(Рез));
Данные.Вставить("dateCreate", ТекущаяДата());
Попытка
ЗаписатьJSON(Запись, Данные, НастройкиСериализации);
Запись.Закрыть();
Возврат Истина;
Исключение
ЗаписьЖурналаРегистрации(ИмяСобытияЖР,УровеньЖурналаРегистрации.Ошибка,,,"Прайс не сформирован, произошла ошибка " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;;
КонецФункции
Функция ТабЗначВМассив(ТаблицаЗначений) Экспорт
НашМассив = Новый Массив;
Для Каждого СтрокаТаблицы из ТаблицаЗначений Цикл
НашаСтруктура = Новый Структура;
Счетчик = 0;
Для Каждого СтрокаСтруктуры из СтрокаТаблицы Цикл
Если НЕ ТипЗнч(СтрокаСтруктуры) = Тип(ТаблицаЗначений) тогда
НашаСтруктура.Вставить(ТаблицаЗначений.Колонки[Счетчик].Имя,СтрокаТаблицы[Счетчик]);
Иначе
НашаСтруктура.Вставить(ТаблицаЗначений.Колонки[Счетчик].Имя,ТабЗначВМассив(СтрокаСтруктуры));
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
НашМассив.Добавить(НашаСтруктура);
КонецЦикла;
Возврат(НашМассив);
КонецФункции
Отправка POST-запроса с JSON в 1с
Тут уже попотеть пришлось чуточку больше, так как данную задачу решал впервые, и быстрое гугление не дало результатов. Все примеры которые находил были разрозненны и по каким то причинам не работали. Возможно у меня руки не оттуда растут, не отрицаю. 🙂
Полученный на предыдущем этапе файл мы должны отправить. Делается это так.
Функция ОповеститьСервер(ФайлПрайса, URLСайта, Ресурс) Экспорт
ФайлОтправки = Новый Файл(ФайлПрайса);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
ЗаголовокЗапросаHTTP = Новый Соответствие();
// Передаем в заголовках размер и тип данных на отправку
ЗаголовокЗапросаHTTP.Вставить("Content-Length", РазмерФайлаОтправки);
ЗаголовокЗапросаHTTP.Вставить("Content-Type", "application/json; charset=utf-8");
HTTP = Новый HTTPСоединение(URLСайта,8000); //Адрес сайта и порт если потребуется. пример - http://localhost:8000
запросPOST = Новый HTTPЗапрос(Ресурс, ЗаголовокЗапросаHTTP); // адрес url веб-сервиса /api/v1/datafill/
запросPOST.УстановитьИмяФайлаТела(ФайлПрайса);
Попытка
//Отправляем для обрааботки на наш сервер
ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Информация, , , "Начало отправки запроса");
ФайлРезультата = ПолучитьИмяВременногоФайла();
HTTPОтвет = HTTP.ОтправитьДляОбработки(запросPOST, ФайлРезультата);
ТекстовыйФайлОтвет = Новый ТекстовыйДокумент;
ТекстовыйФайлОтвет.Прочитать(ФайлРезультата,КодировкаТекста.UTF8);
ОтветСервера = ТекстовыйФайлОтвет.ПолучитьТекст();
ОтветСервера = HTTPОтвет.ПолучитьТелоКакСтроку();
ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Информация, , , "Ответ сервера: " + ОтветСервера);
Исключение
ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Ошибка, , , "Ответ сервера: " + ОписаниеОшибки());
КонецПопытки;
Возврат ОтветСервера;
КонецФункции
Стоит отметить что данные будут отправлены в теле запроса, а не в параметрах POST.
