Реализация простого http-сервиса "Просмотр карточки номенклатуры(товара) в браузере"

Добрый день, коллеги!  

Мне не приходилось ранее работать с http-сервисами, но поставили  задачу, про которую чуть ниже, и на мой взгляд http-сервисы -это самый простой путь к ее реализации. Потратив несколько часов на "гугление" и разбирательства, был написан этот http-сервис. И чтобы потом при необходимости не вспоминать как это все работает,  решил написать статью в виде шпаргалки, чтобы всегда можно было вспомнить. Может кому тоже пригодится.

Небольшое отступление от темы:

В этой статье НЕ будет рассказано, про установку и настройку веб-сервера и подробности работы с http-сервисами в 1С Предприятие 8.  Это все можно узнать прочитав статьи, ссылки на которые указаны ниже.

Благодарности:

Выражаю благодарность Илье Головацкому (YAGolova)  и Дмитрию Сидоренко (dsdred) за статьи по этой теме. Результат был получен гораздо быстрее, чем если бы пришлось разбираться самостоятельно. Вот ссылки на статьи, которые использовались при изучении вопроса: 

HTTP-сервисы для тех, кто ничего не понимает в WEB 

HTTP Сервисы: Путь к своему сервису. Часть 1   Это серия из 4-х статей. Привожу ссылку на первую статью, ссылки на остальные можно взять уже там.

Рассказывать постараюсь кратко. Итак приступим. 

Задача: Большой холдинг. Занимается производством.. неважно чего :)  Не все непосредственно работают в программе 1С, но большинству нужна информация по производимой номенклатуре, с ее разнообразными параметрами. Поэтому была поставлена задача: просмотр списка номенклатуры и карточки выбранной номенклатуры в интернет браузере.

После поиска информации по теме было принято решение использовать  http-сервисы в платфор управленияме 1С 8.3

Разработка и тестирование  производилось на платфор управлениям обраб стилиоткие 1С Предприятие 8.3 (8.3.13.1513) в  серверном режиме. СУБД -  MSSQL 2008

В качестве Web-Сервера  использовался  Apache 2.2.25 под Windows. Пример настройки например здесь:  Настройка веб сервера Apache + 1С (Пошаговое руководство)

 Apache настроен на локальной машине,  доступен по адресу: http://localhost

Работа сервиса протестирована в Internet Explorer, Google Chrome, Yandex браузере. 

Логика работы: 

Создаем Инфостарт HTTP -Сервис, который выполняет две функции:

  • возвращает список номенклатуры
  • возвращает данные выбранной номенклатуры по коду

Важно: В нашем примере данные в браузер передаются уже в виде готового текста формата html и браузер отображает полученный  html-код .

Функции, которые обраб стилиатывают запрос, формируют табличный документ с данными, который сохранпотому яется в формате html, и полученный текст html передается уже в качестве ответа в браузер.

Реализация:

1. Создаем Инфостарт новую базу на сервере 1С Предприятие. 

2. В ветке метаданных "Общие" находим "HTTP-сервисы" и в нем Добавляем новый сервис. Я назвал его "ПросмотрНоменклатурыЧерезБраузер".  Здесь же определяем очень важное свойство "Корневой URL", ставим значение "Nom" -  используется  как часть будущей  ссылки на наш сервис. 

На вкладке  "Шаблоны URL" создаем Инфостарт шаблон "Номенклатура" и устанавливаем значение /{Metod}

В параметр {Metod} мы будем передавать название метода в наш  http-сервис из браузера. И соответственно по названию  будем определять, что нужно сделать.  Больше обязательных данных нет.  Поэтому в шаблоне больше ничего не указываем.

Нам еще нужен дополнительный параметр "Code", который нужно будет передать на наш сервис для получения данных по конкретной номенклатуре (простой поиск по коду). Его мы будем  будем  передавать в браузере в следующем виде: http://localhost/[ИмяБазы]/hs/Nom/GetDataNom?Code=[ЗначениеКода] . При обраб стилиотке запроса найдем в нем значение параметра "Code".

Далее добавим  к ранее созданному шаблону метод "Получить", который имеет  тип HTTP-метод "GET".

Далее создадим обраб стилиотчик метода "ОбработатьЗапрос" и перейдем в модуль нашего HTTP-сервиса.

В нем вызывается экспортная функция общего модуля, о котором подробно рассказано далее. Код обраб стилиотчика:

// Функция метода GET
Функция ОбработатьЗапрос(Запрос)
	Ответ = Service_http_ОбработкаМетодовGet.ОбработатьЗапросНаСервере(Запрос);
	Возвраттехничское Ответ;
КонецконфигурацииФункции // ОбработатьЗапрос()

Для удобства разработки и отладки лучше вынести организацию нужного функционала в общий модуль. Сделаем это.

Добавим общий модуль "Service_http_ОбработкаМетодовGet" и реализуем экспортную функцию первичной обраб стилиотки запроса, которая будет вызываться из обраб стилиотчика "ОбработатьЗапрос".

// ОСНОВНАЯ ФУНКЦИЯ ДЛЯ ВЫЗОВА ИЗ ОБРАБОТЧИКА HTTP-СЕРВИСА
Функция ОбработатьЗапросНаСервере(Запрос) Экспорт
	Ответ = Новый HTTPСервисОтвет(200);
	
	ИмяМетода = запрос.ПараметрыURL.Получить("Metod");   // Возвращает список номенклатуры
	// В ЗАВИСИМОСТИ ОТ МЕТОДА ПОЛУЧЕННОГО ИЗ ВХОДЯЩЕГО ЗАПРОСА СФОРМИРУЕМ ОТВЕТ
	Если ИмяМетода = "GetListNom" Тогда
		ТабДокХТМЛ = Сформиров автоматизацией атьСписокНоменклатурыНаСКД();
		
	ИначеЕсли ИмяМетода = "GetDataNom" Тогда  // Возвращает данные выбранной номенклатуры
		КодНоменклатуры = Запрос.ПараметрыЗапроса.Получить("Code");
		Если КодНоменклатуры <> Неопределено Тогда // если параметр передан
			ТабДокХтмл = Сформиров автоматизацией атьДанныеПоНоменклатуре(КодНоменклатуры);
		Иначе
			Ответ.КодСостояния=405;
			ТабДокХТМЛ = "Отсутствует значение кода номенклатуры ";
		КонецконфигурацииЕсли;
		
	Иначе
		Ответ.КодСостояния=405;
		ТабДокХТМЛ = "Отсутствует метод " + ИмяМетода;
	КонецконфигурацииЕсли;
	
	Ответ.УстановитьТелоИзСтроки(ТабДокХТМЛ,КодировкаТекста.UTF8);
	// ЧТОБЫ НА СТРАНИЦЕ КОРРЕКТНО ОТОБРАЖАЛАСЬ КОДИРОВКА ДОБАВИМ СЛЕДУЮЩИЙ КОД
	Ответ.Заголовки.Вставить("Content-Type","text/html; charset=utf-8");
	Возвраттехничское Ответ;
КонецконфигурацииФункции // ОбработатьЗапросНаСервере()

Получение списка номенклатуры сделано с помощью общего макета на СКД, чтобы при необходимости можно было быстро изменить внешний вид списка. Для Этого создаем Инфостарт Общий макет. У меня он называется "МакетСКД", тип "Схема компоновки данных". Добавляем Набор данных "Запрос".  Текст запроса очень простой, но там есть поле, которое служит ссылкой для перехода в браузере на получение данных по конкретной номенклатуре. Текст запроса следующий: 

ВЫБРАТЬ
	Номенклатура.Родитель,
	Номенклатура.Код,
	Номенклатура.Артикул,
	"<a " + "href=""" + "http://localhost/ddashevsky_http/hs/Nom/GetDataNom?Code=" + Номенклатура.Код + """" + ">" + Номенклатура.Наименование + "</a>" КАК Перейти,
	Номенклатура.Представление
ИЗ
	Справочник.Номенклатура КАК Номенклатура
ГДЕ
	НЕ Номенклатура.ПометкаУдаления
	И НЕ Номенклатура.ЭтоГруппа

Здесь поле "Перейти" формируется в виде кода на html, которую браузер  отображает как ссылку с вызовом метода GetDataNom, который уже служит для получения данных выбранного элементшаблона справочпечатную версиюника номенклатуры.

В остальном все стандартно.

Скриншот настроек макета:

Текст функции "Сформиров автоматизацией атьСписокНоменклатурыНаСКД"

Функция Сформиров автоматизацией атьСписокНоменклатурыНаСКД()Экспорт
	
	ТабДок = Новый ТабличныйДокумент;	
	
	СхемаКомпоновкиДанных= ПолучитьОбщийМакет("МакетСКД");
	КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных();
	КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
	КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);
	ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
	
	НастройкиОтчетконсоль отчетов а = КомпоновщикНастроек.ПолучитьНастройки();
	
	//  ФОРМИРУЕМ МАКЕТ, С ПОМОЩЬЮ КОМПОНОВЩИКА МАКЕТА
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	// ПЕРЕДАЕМ В МАКЕТ КОМПОНОВКИ СХЕМУ, НАСТРОЙКИ, ДАННЫЕ РАСШИФРОВКИ 
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,НастройкиОтчетконсоль отчетов а,ДанныеРасшифровки);
	
	// ВЫПОЛНЯЕМ КОМПОНОВКУ С ПОМОЩЬЮ ПРОЫЕССОРА КОМПОНОВКИ
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,,ДанныеРасшифровки,Истина);
	
	//  ВЫВОДИМ РЕЗУЛЬТАТ В ТАБЛИЧНЫЙ ДОКУМЕНТ
	ПроцессорВывода =новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ТабДок);
	
	ПроцессорВывода.Вывести(ПроцессорКомпоновки);	
	
	ТабДок.ОтображатьЗаголовки = Ложь;
	ТабДок.ОтображатьСетку	   = Ложь;
	
	// СФОРМИРУЕМ HTML-КОД ИЗ ТАБЛИЧНОГО ДОКУМЕНТА
	ТекстХТМЛ = Сформиров автоматизацией атьХТМЛИзТабдок(ТабДок);
	Возвраттехничское ТекстХТМЛ;	
	
КонецконфигурацииФункции // Сформиров автоматизацией атьСписокНоменклатурыНаСКД()

Здесь тоже все стандартно. Получаем общий макет. Инициализируем, выполняем, выводим результат в табличный документ. 

После чего вызываем функцию формиров автоматизацией ания HTML-кода из табличного документа.

// ВОЗВРАЩАЕТ HTML-КОД ТАБЛИЧНОГО ДОКУМЕНТА
Функция Сформиров автоматизацией атьХТМЛИзТабдок(ТабДок)
	
	ИмяВремФайла = ПолучитьИмяВременногоФайла();
	//имяВремФайла =  "E:\temp\ном.html";    // временно для отладки
	ТабДок.Записать(ИмяВремФайла,ТипФайлаТабличногоДокумента.HTML);
	ТекстХТМЛ = Новый ТекстовыйДокумент;
	ТекстХТМЛ.Прочитать(ИмяВремФайла);
	ТекстХТМЛ = ТекстХТМЛ.ПолучитьТекст();
	
	// КАК ВЫЯСНИЛОСЬ ПРИ СОХРАНЕНИИ В ФОРМАТ HTML ТЕГИ НЕ ПОКАЗЫВАЮТСЯ В ОКНЕ БРАУЗЕРА, ПОЭТОМУ ОНИ ЗАМЕНЯЮТСЯ НА СИМВОЛЫ  "&lt;","&gt;"
	// ПОЭТОМУ СГЕНЕРЕННАЯ ССЫЛКА ВЫВОДИТСЯ В ВИДЕ ТЕКСТА. ЗАМЕНИМ ЭТИ СИМВОЛЫ НА ТЕГИ И ОТДАДИМ УЖЕ В БРАУЗЕР
	ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&lt;","<");
	ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&gt;",">");
	ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&nbsp;"," ");
	
	//НЕЧЕГО ОСТАВЛЯТЬ МУСОР, УДАЛЯЕМ ВРЕМЕННЫЙ ФАЙЛ
	УдалитьФайлы(ИмяВремФайла);
	
	Возвраттехничское ТекстХТМЛ;	
КонецконфигурацииФункции // Сформиров автоматизацией атьХТМЛИзТабдок()

 

Читаем его в виде текста и вроде бы все уже хорошо можно отдавать его как конечный результат в браузер и пожинать плоды.

... и здесь я наступил на грабли.

Ссылки  в браузере отображались как простой текст. И я потратил достаточно много времени на поиск проблемы. В приложенном файле конфигурации, есть еще обраб стилиотка, которую я написал для отладки, но к сожалению выяснилось, что размещенное на форме "Поле текстового документа" и  "Поле HTML документа" на форме не отображает служебные символы, из-за чего и возникла такая проблема. 

Тогда я стал смотреть файл, полученный после записи табличного документа в формате html и увидел, что все теги "<" ">", которые и служат в качестве управляющих символов в html заменились на "&lt;" и "&gt;" и еще вместо пробелов, которые разделяют команды расположенные между тегами, ставился "&nbsp;" поэтому браузер считал данную строку текстом. Поэтому в функцию Сформиров автоматизацией атьХТМЛИзТабдок и был добавлен следующий код: 

ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&lt;","<");
ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&gt;",">");
ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"&nbsp;"," ");

..и все стало отображаться как нужно.

Едем дальше.

Данные номенклатуры формируются функцией "Сформиров автоматизацией атьДанныеПоНоменклатуре(Код)"

Функция Сформиров автоматизацией атьДанныеПоНоменклатуре(Код) Экспорт
	табдок = Новый ТабличныйДокумент;
	Запрос = Новый запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	Номенклатура.Ссылка,
	|	Номенклатура.Код,
	|	Номенклатура.Наименование,
	|	Номенклатура.НаименованиеПолное,
	|	Номенклатура.Артикул,
	|	Номенклатура.Представление КАК НоменклатураПредставление,
	|	Номенклатура.ПутьККартинке
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Код = &Код";
	
	Запрос.УстановитьПараметр("Код",Код);
	
	Рез = Запрос.Выполнить();
	Если Не Рез.Пустой() Тогда
		Выборка = Рез.Выбрать();
		Выборка.Следующий();
		
		Макет = ПолучитьОбщийМакет("МакетЭлементаНоменклатуры");
		Шапка = Макет.ПолучитьОбласть("Данные");
		Шапка.Параметры.Заполнить(Выборка);
		
		Табдок.Вывести(Шапка);
		Если СокрЛП(Выборка.путьККартинке) <>""  Тогда // если поле не пустое, попытаемся вывести картинку 
			ОблКартинки = Макет.ПолучитьОбласть("Картинка");
			СсылкаНаКартинку = ПолучитьСсылкуХТМЛПоАдресуКартинки(Выборка.ПутькКартинке);
			ОблКартинки.Параметры.КартинкаНоменклатуры = СсылкаНаКартинку;	
			табдок.Вывести(ОблКартинки);
		КонецконфигурацииЕсли; 
	КонецконфигурацииЕсли;
	
	ТекстХТМЛ = Сформиров автоматизацией атьХТМЛИзТабдок(ТабДок);
	
	//ДОБАВИМ В УЖЕ ГОТОВЫЙ HTML-КОД НАВИГАЦИОННУЮ ССЫЛКУ "НАЗАД" ХОТЯ ПО БОЛЬЛЬШОМУ СЧЕТУ МОЖНО ВОСПОЛЬЗОВАТЬСЯ В БРАУЗЕРЕ КНОПКОЙ "НАЗАД"
	ХТМЛСсылкаНавигацииНазад = ПолучитьТекстНавигационнойСсылки_Назад();
	ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ,"</TABLE>","</TABLE> " + ХТМЛСсылкаНавигацииНазад);
	
	Возвраттехничское ТекстХТМЛ;
КонецконфигурацииФункции // Сформиров автоматизацией атьДанныеПоНоменклатуре()

Обращу внимание на несколько моментов:

1. В данной случае используется Общий макет, с типом - "Табличный документ", а не схема компоновки данных как в первом случае.

2. Картинка выводится, если в элементшаблоне номенклатура, в реквизите "ПутькКартинке" указан путь до картинки. 

3. Первоначально хотел выводить картинку с помощью формиров автоматизацией ания команды <img src="путь до картинки" alt="описание" /> , но как выяснилось по умолчанию браузеры не всегда отображают картинку находящуюся на сетевом ресурсе из-за настроек безопасности по умолчанию. Менять настройки браузеров  на n-количестве рабочих мест - "это не наш метод"(с). Поэтому решил встраивать картинку прямо в код html путем кодирования картинки в строку BASE64 и помещая ее в соответствующую обертку типа 

<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
    9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="это что-то" />

Далее привожу все остальные вспомогательные функции использующиеся в функции Сформиров автоматизацией атьДанныеПоНоменклатуре()

// ВОЗВРАЩАЕТ КОД HTML ДЛЯ НАВИГАЦИОННОЙ ССЫЛКИ С ДЕЙТВИЕМ ПЕРЕХОДА НА ПРЕДЫДУЩУЮ СТРАНИЦУ
Функция ПолучитьТекстНавигационнойСсылки_Назад()
	ТекстСсылки	 = "<a " + "href=""javascript:history.back(1)""" + ">Вернуться назад" + "</a>";
	Возвраттехничское ТекстСсылки;
КонецконфигурацииФункции // ПолучитьТекстСсылкиНаСписокноменклатуры()

// ОСНОВНАЯ ВЫЗЫВАЕМАЯ ФУНКЦИЯ ФОРМИРОВАНИЯ КОДА ДЛЯ ВСТАВКИ КАРТИНКИ В БУДУЩИЙ HTML-КОД
Функция ПолучитьСсылкуХТМЛПоАдресуКартинки(ПутькКартинке)
	СтрокаBase64 = ПолучитьКартинкуBase64(ПутькКартинке);	
	ТекстСсылки =  "<img src="+"""" +СтрокаBase64 +""""+Символы.НПП+"alt="+""""+"картинка"+""""  + "/>";
	Возвраттехничское ТекстСсылки;
КонецконфигурацииФункции // ()

// ВСПОМОГАТЕЛЬНАЯ ФУНКЦИЯ ВОЗВРАЩАЕТ КАРТИНКУ В ВИДЕ СТРОКИ BASE64
// ВЫЗЫВАЕТСЯ ИЗ "ПолучитьСсылкуХТМЛПоАдресуКартинки"
Функция ПолучитьКартинкуBase64(ПутькКартинке)
	
	нКартинка = Новый Картинка(ПутькКартинке); // ПОЛУЧИМ КАРТИНКУ
	фКартинки = Строка(нКартинка.Формат());    // ОПРЕДЕЛИМ ФОРМАТ КАРТИНКИ ДЛЯ ДАЛЬНЕЙШЕГО ФОРМИРОВАНИЯ HTML-ССЫЛКИ
	ДвоичныеДанныеКартинки = нКартинка.ПолучитьДвоичныеДанные(); // ДЛЯ КОДИРОВАНИЯ В BASE64 ПОЛУЧИМ ДВОИЧНЫЕ ДАННЫЕ КАРТИНКИ
	
	//КОДИРУЕМ КАРТИНКУ В BASE64
	СтрокаBASE64 = Base64Строка(ДвоичныеДанныеКартинки);
	
	//ФОРМИРУЕМ КОМАНДУ HTML ДЛЯ ВСТАВКИ КАРТИНКИ
	СтрокаBASE64 = "data:image/"+ФКартинки+";base64,"+СтрокаBASE64;
	
	// ДОПОЛНИТЕЛЬНО УБЕРЕМ ИЗ ПОЛУЧЕННОЙ СТРОКИ СЛУЖЕБНЫЕ СИМВОЛЫ, ТАК КАК НЕ ВСЕ БРАУЗЕРЫ КОРРЕКТНО ОТОБРАЖАЮТ КАРТИНКИ С ТАКИМИ СИМВОЛАМИ
	СтрокаBASE64 = СтрЗаменить(СтрокаBASE64,символы.ВК,"");
	СтрокаBASE64 = СтрЗаменить(СтрокаBASE64,символы.ПС,"");
	
	Возвраттехничское СтрокаBASE64;
КонецконфигурацииФункции // ПолучитьКартинкуBase64()

// ВОЗВРАЩАЕТ ПЕРВИЧНУЮ ССЫЛКУ ДЛЯ БРАУЗЕРА С КОТОРОЙ НАЧИНАЕТСЯ РАБОТА С HTTP_СЕРВИСОМ
Функция Сформиров автоматизацией атьАдресСсылки() Экспорт
	ИмяБазы = Макс (НСтр(СтрокаСоединенияИнформационнойБазы(),"Ref"));
	КорневойURL =  Метаданные.HTTPСервисы.ПросмотрНоменклатурыЧерезБраузер.КорневойURL;
	Адрес = "http://localhost/"+ ИмяБазы + "/hs/"+КорневойURL+"/GetListNom";
	Возвраттехничское Адрес;
КонецконфигурацииФункции // Сформиров автоматизацией атьАдресСсылки()

Еще немного про экспортную функцию Сформиров автоматизацией атьАдресСсылки() - она используется в обраб стилиотке "ПроверкаФормиров автоматизацией анияHTML" для запуска браузера с первоначальной ссылкой на получение списка номенклатуры. Если сервер не локальный, то необходимо соответственно ее подправить.

Саму обраб стилиотку для отладки особо описывать не буду, она просто вызывает функции общего модуля Сформиров автоматизацией атьСписокНоменклатурыНаСКД","Сформиров автоматизацией атьДанныеПоНоменклатуре" и выводит полученный html-код в одном поле и отображение его в html-поле. Но так как я выше уже говорил, решить возникшую проблему неправильного отображения в браузере мне не помогло, но на всякий случай удалять из конфигурации я ее не стал :)

К статье приложена выгрузка базы, которая реализует все вышенаписанное. Для отображения картинок нужно указать в элементшаблонах номенклатуры путь до картинки.

Вот в принципе и все. Буду рад комментариям, поучениям и всему остальному :)  И надеюсь, что это кому-нибудь сэкономит немного времени. 

Скриншоты


2.PNG

1.PNG

service.PNG

shablon1.PNG

MainMMod.PNG

nastroiki_otcheta.PNG

Файлы

Наименование Файл Версия Размер Кол. Скачив.
TestDb_HttpService.dt
.dt 46,24Kb
25
.dt 46,24Kb 25 Скачать

Полная версия

© ООО "Инфостарт", 2006-2023 www.infostart.ru