1c http сервисы
Задача: Написать простой обмен между конфигурациями, используя http-сервис.
Исходные данные: В базе управленческого учета (далее “fin“) пользователи заводят банковские счета (далее БС). Необходимо при записи их передавать в бухгалтерскую базу (далее “upp“) и создавать его там при отсутствии.
Решение: Нижеописанный метод реализован на http-сервисе под управлением “IIS”. Так же его можно и реализовать на веб-сервере “Apache”.
Внимание! Подразумевается что ISS (или Apache) уже настроен на сервере и функционирует. При отсутствии настроенного ISS, крайне рекомендую установить веб-сервер Apache, так как он намного проще и понятнее.
Приступаем! В базе приемники “upp” создаем http-сервис “exchange_buh”:
Особое внимание стоит обратить на свойство “Корневой URL” – это по сути идентификатор http-сервиса (ссылка на веб-сервис).
Далее добавляем шаблон URL:
Здесь внимание уделяем свойству “Шаблон” – в нашем случае укажем идентификатор “data_fin” (произвольное), через который будет происходить обращение к нашему сервису, и переменную “{InfoType}”, значение который мы будем передавать и обрабатывать в базе “upp“. Внимание: “{InfoType}” – это не основные наши передаваемые данные. Это просто вспомогательные данные для обработки.
И осталось добавить только основной метод нашего сервиса:
Здесь указываем в свойстве “HTTP-метод” значение “POST”. Метод запроса POST – это метод, при котором веб-сервер принимает данные, заключенные в тело сообщения.
Теперь наступает самый ответственный момент – публикация веб-сервиса. Для этой операции запускаем “конфигуратор” под администратором системы (зажимаем клавишу “SHIFT” и в контекстном меню выбираем пункт “Запуск от имени администратора”):
В “конфигураторе” через меню “Администрирование/Публикация на веб-сервере…” открываем настройки публикации и публикуем:
В результате такой публикации через “ISS” сервер у нас образуется каталог с файлами:
Имя, указанное при публикации на веб-сервере, будет соответствовать названию каталога, в котором будет храниться описание нашего веб-сервиса.
Теперь приступаем к самому интересному – программированию.
В конфигурации “fin”, откуда мы передаем данные, каждый раз, при записи БС, вызываем нашу процедуру передачи данных “барк_httpСервисы.ОтправитьБанковскийСчетВБухглатерию“
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Процедура ПриЗаписи(Отказ) Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли; //{Чак Норрис 12.08.2019 Если Не Отказ Тогда барк_httpСервисы.ОтправитьБанковскийСчетВБухглатерию(Ссылка); КонецЕсли; //} КонецПроцедуры |
Ну и соответственно наша главная процедура обмена:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Процедура ОтправитьБанковскийСчетВБухглатерию(п_ссылка) Экспорт //++Формируем JSON с данными ДаныеДляОтправки = Новый Структура(); ДаныеДляОтправки.Вставить("ГУИД_Контрагента" , Строка(п_ссылка.Владелец.УникальныйИдентификатор())); ДаныеДляОтправки.Вставить("НаименованиеСчета", СокрЛП(п_ссылка.Наименование)); ДаныеДляОтправки.Вставить("НомерСчета" , СокрЛП(п_ссылка.НомерСчета)); ДаныеДляОтправки.Вставить("БикБанка" , СокрЛП(п_ссылка.Банк.Код)); ДаныеДляОтправки.Вставить("КодВалюты" , СокрЛП(п_ссылка.ВалютаДенежныхСредств.Код)); ТекЗаписьJSON = Новый ЗаписьJSON; ТекЗаписьJSON.УстановитьСтроку(); ЗаписатьJSON(ТекЗаписьJSON, ДаныеДляОтправки); ТекстJSON = ТекЗаписьJSON.Закрыть(); //--Формируем JSON с данными КодОперации = "bank_account"; //Код операции - по нему будем ориентироваться на действия, которые необходимо будет выполнить на стороне htpp сервиса ИмяСервера = "СерверПлутон"; //имя компьютера где опубликован наш сервис Порт = 80; //порт на сервере для ISS или Apache, по умолчанию 80, но может быть и любой другой ИмяПользователя = "HTTPServiseAdmin"; //Имя пользователя(с полными правами) из базы 1с, где был описан наш сервис Пароль = "123321"; //Пароль пользователя HTTP = Новый HTTPСоединение(ИмяСервера, Порт, ИмяПользователя, Пароль); запросPOST = Новый HTTPЗапрос(); запросPOST.АдресРесурса = "/" + "TEST_7_all_accounting" + "/hs/exchange_buh/data_fin/" + КодОперации + "/";//Адрес http сервиса на сервере запросPOST.Заголовки.Вставить("Content-type", "application/json; charset=utf-8"); запросPOST.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); //упаковываем наш текст JSON HTTPОтвет = HTTP.ОтправитьДляОбработки(запросPOST); //отправляем Если НЕ HTTPОтвет.КодСостояния = 200 Тогда //получаем сформированные ответы от http-сервиса ТекстСообщения = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8"); Сообщить("Код состояния: " + HTTPОтвет.КодСостояния + ". |" + ТекстСообщения + ". |Не удалось синхронизировать банковские счета с базой УПП!"); Иначе ТекстСообщения = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8"); Сообщить(ТекстСообщения); КонецЕсли; КонецПроцедуры |
Все просто – основные комментарии указаны в вышеприведенном коде. Вниманием уделяем строке подключения к сервису:
Вернувшись к структуре нашего сервиса и его свойствам, вы легко разберетесь что здесь к чему.
Внимание! Хранение логинов и паролей в коде не приемлемо! Используйте Безопасное хранилище данных 1с.
И наконец-то код на стороне приема данных “upp”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
Функция POST_data_fin(Запрос) ЗапрашиваемаяИнформация = Запрос.ПараметрыURL.Получить("InfoType"); Сообщение = Запрос.ПолучитьТелоКакСтроку("UTF-8"); //здесь описываем имена всех полей с датами для их преобразования в формате дат МассивДат = СтрРазделить("Период |ДатаВыдачи |Дата |ВыбДата", Символы.ПС, Ложь); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(Сообщение); ДанныеИзФинансов = ПрочитатьJSON(ЧтениеJSON, Ложь, МассивДат, ФорматДатыJSON.ISO); ЧтениеJSON.Закрыть(); Если ЗапрашиваемаяИнформация = "bank_account" Тогда Успешно = Истина; СоздатьБанковскийСчет(ДанныеИзФинансов, Успешно); Если Успешно Тогда HTTPОтвет = Новый HTTPСервисОтвет(200); ТекстСообщения = "Банковский счет успешно создан в УПП!"; HTTPОтвет.УстановитьТелоИзСтроки(ТекстСообщения); Иначе HTTPОтвет = Новый HTTPСервисОтвет(500); ТекстСообщения = "Ошибка создания банковского счета в УПП! "; HTTPОтвет.УстановитьТелоИзСтроки(ТекстСообщения); КонецЕсли; Иначе HTTPОтвет = Новый HTTPСервисОтвет(500); ТекстСообщения = "Неверный тип запрашиваемой информации! Допустимые значения: bank_account"; HTTPОтвет.УстановитьТелоИзСтроки(ТекстСообщения); ЗаписьЖурналаРегистрации("HTTPСервисы.exchange_buh", УровеньЖурналаРегистрации.Информация, Метаданные.HTTPСервисы.exchange_buh, , ТекстСообщения); КонецЕсли; Возврат HTTPОтвет; КонецФункции |
В результате вызова метода сервиса мы получим наши параметры: “ДополнительныйПараметр” и “ОсновныеДанные”:
И сама процедура создания БС по переданным параметрам:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
Процедура СоздатьБанковскийСчет(п_данные, п_успешно) СсылкаОбъекта = Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(п_данные.ГУИД_Контрагента)); ОбъектКонтрагент = СсылкаОбъекта.ПолучитьОбъект(); Если НЕ ОбъектКонтрагент = Неопределено Тогда //Если владелец счета есть в базе, то создаем его банковский счет НайденнаяСсылка = Справочники.БанковскиеСчета.НайтиПоРеквизиту("НомерСчета", п_данные.НомерСчета, , СсылкаОбъекта); Если НЕ НайденнаяСсылка = Справочники.БанковскиеСчета.ПустаяСсылка() Тогда // //Счет есть и его создавать не нужно Иначе БанковскийСчет = Справочники.БанковскиеСчета.СоздатьЭлемент(); БанковскийСчет.Владелец = СсылкаОбъекта; Валюта = Справочники.Валюты.НайтиПоКоду(п_данные.КодВалюты); Если ЗначениеЗаполнено(Валюта) Тогда БанковскийСчет.ВалютаДенежныхСредств = Валюта; Иначе БанковскийСчет.ВалютаДенежныхСредств = Константы.ВалютаРегламентированногоУчета.Получить(); КонецЕсли; БанковскийСчет.ВидСчета = "Расчетный"; Банк = Справочники.Банки.НайтиПоКоду(п_данные.БикБанка); Если Не Банк = Справочники.Банки.ПустаяСсылка() Тогда БанковскийСчет.Банк = Банк; КонецЕсли; БанковскийСчет.НомерСчета = п_данные.НомерСчета; БанковскийСчет.Наименование = п_данные.НаименованиеСчета; Попытка БанковскийСчет.Записать(); Исключение п_успешно = Ложь; КонецПопытки; КонецЕсли; Иначе п_успешно = Ложь; КонецЕсли; КонецПроцедуры |
В этом примере в качестве основного параметра передаем ‘Структуру‘, но можем отправлять и другие значения: к примеру ‘Массив Структур‘, так же преобразованную в формат JSON.
С помощью метода “HTTPОтвет = Новый HTTPСервисОтвет()” формируем возвращаемое значение:
Вот таким элементарным способом, буквально за полдня, пишется обмен.
Ссылка на конфигурацию с “htpp-сервисом” и программными модулями.
P.S. Практический материал (алгоритмы, htpp-сервис) предоставлен пользователем FANTASISTO.
Огромное СПАСИБО автору.
Да не за что, пользуйся!
Все сделал как у Вас написано.. Но почему то мне все время возвращается 404 ошибка.. ( Соединение c HTTP-сервисом происходит – есть соответствующие записи в журнале регистрации. Но дальше дело не идет, адрес ресурса видимо не распознается и возвращает 404. Чего только не перепробовал, и публикацию делал не через конфигуратор на локальный сервер, а через утилиту webinst на тот сервер, на котором серверная часть базы.. Ничего не помогает.. Не подскажите – что можно еще попробовать?
Привет. Сервис публиковал из конфигуратора запущенным под админом? С доступом к папке сервиса все в порядке? Проверь еще раз “запросPOST.АдресРесурса” адрес ресурса, я помню когда писал в первый раз, не верно его формировал под структуру сервиса. Долго с этим промучился. Получается он даже не заходит в процедуру сервиса? На данный момент есть настроенные и рабочие веб/htpp сервисы у этой базы или этой первые сервисы для неё?
Добрый день. Да, сервис публиковался под админскими правами, доступ к папке есть. Согласен, что видимо дело в “запросPOST.АдресРесурса”, но что в нём может быть неправильного не пойму.. Формирую его под структуру сервиса в полном соответствии с правилами://hs////. Код операции – произвольная строка, которая задается в клиентской программе и сравнивается в серверной. Но собственно до сравнения дело не доходит.. Чем то ей это адрес ресурса не нравится, не находит она его.. Написал для примера GET-запрос и проходит и из браузера и из 1с. Например localhost/up_develop_2/hs/Users?action=getusers или из 1с: HTTP.Получить(“/up_develop_2/hs/Users?action=getusers”, имяВыходногоФайла); А вот POST запрос не проходит, хоть ты тресни.. Измучился уже с ним..
В понедельник на работе гляну свой http сервис, может чего дельного подскажу. Уверен проблема скорее всего у тебя ерундовая, но докопаться бы до неё…
Интересно, почему то удалились из сообщения все строки в угловых скобках. Должно быть вот так (без угловых скобок): Имя публикации/hs/корневой URL/шаблон/Код операции
Посмотрел у себя. Вроде все как и должно быть. Вот есть какая мысль – может быть у тебя в модуле сервиса ошибка (там программа на синтаксис не проверяет): попробуй в модуле сервиса оставить к примеру только “Сообщить(“Тест”)” или вообще просто в методе код весь закоментить. И проверь будет ли соединяться в этом случае.