воскресенье, 14 октября 2012 г.

1С:Предприятие 8. Веб-сервисы. Реализация веб-сервиса

Содержание статей: 1С:Предприятие 8. Веб-сервисы
Предыдущая статья: 1С:Предприятие 8. Веб-сервисы. Введение


Для создания самого простого веб-сервиса необходимо:
  1. создать в дереве метаданных объект Web-Сервис;
  2. указать его URI пространства имен;
  3. создать необходимую операцию, если нужно указать ее параметры и тип возвращаемого значения;
  4. написать обработчик вызываемой операции;
  5. опубликовать веб-сервис.
После этих действий веб-сервисом можно будет пользоваться. Таким образом будет создан веб-сервис, который сможет оперировать только простыми типами данных. 

Итак начнем.
Откройте конфигурацию и в дереве метаданных найдите ветку "Общие - Web-сервисы". Нажмите правой кнопкой и добавьте новый элемент.

Реализация веб-сервиса в 1с

Введите имя создаваемого веб-сервиса.
Имя веб-сервиса можно задать русское. И платформа его сохранит и опубликует, но рекомендую использовать латиницу в названиях веб-сервисов,  ws-операций, параметров ws-операций. Например, chrome не смог отобразить wsdl файл веб-сервиса с русским именем.
Перейдите на вкладку  "Прочее" и укажите параметр "URI пространство имен".

Реализация веб-сервиса в 1с

В документации об этом параметре написано чуть больше чем ничего, примерно то, что это поле служит для идентификации вашего веб-сервиса. Когда я делал свой первый веб-сервис, мне казалось что это ссылка на сайт, на котором я публикую свой веб-сервис и все наименования буду получаться через запрос к этому сайту. На самом деле "URI пространство имен" не что иное как строка определяющая название набора ваших имен (названий веб-сервиса, операций, параметров, типов данных и т.д.). То есть если вы объявите свой тип "integer" то xml-парсер не будет ругаться, так как этот тип принадлежит вашему пространству имен. Мало того если "URI пространство имен" будет содержать русские символы и не будет соответствовать стандарту как формат URI, платформа все равно опубликует такой веб-сервис, и он будет работать. Но по стандартам рекомендуется использовать URI ссылку. Я советую того же самого.
Простое и понятное объяснение пространства имен можно прочитать тут.

Поле "Пакеты XDTO" не обязательное. Оно определяет набор пакетов XDTO в которых вы можете оказать свои типы значений. Это не обязательное поле, по умолчанию вам всегда доступны типы пространства имен "http://www.w3.org/2001/XMLSchema". О пакетах XDTO я расскажу чуть позже.

"Имя файла публикации", это имя файла, в котором хранятся настройки веб-сервиса для Apache(путь к базе и другие) после публикации. Папка, в которой находится этот файл, определяется при публикации. О публикации на веб-сервере будет рассказано позже.

Веб-сервис создан, но еще нет ни одной функции которую он мог бы исполнить. Надо добавить операцию. Для этого добавьте в созданный веб-сервис операцию. Нажмите не веб-веб-сервис правой кнопкой и выберите "Добавить-Операция". Она будет к вашему операнду прибавлять 2 и возвращать значение. Давайте назовем ее "Plus2". Можно указать и русское название, многие клиенты его обработают, но все же могут возникнуть проблемы. 
Реализация веб-сервиса в 1с

"Тип возвращаемого значения" это тип описанный в указанном вами пакете XDTO или же тип из пространства имен "http://www.w3.org/2001/XMLSchema". Именно в этом типе веб сервис будет возвращать значение.
"Возможно пустое значение" признак что ws-операция может не вернуть значение(nillable="true").
"В транзакции" указывает что код веб-сервиса будет выполняться в транзакции. А "Режим управления блокировкой данных" определяет тип блокировки данных при транзакции по умолчанию.

Установим тип возвращаемого значения в int. В поле "Имя метода" укажем имя "Plus2" для нового метода, который будет выполнять обработку. При нажатии на лупу метод будет автоматом создан в модуле веб-сервиса.
Напишем простой код.

Функция Plus2(Параметр)
Возврат Параметр+2;
КонецФункции

Вы заметили что на входе функции у нас есть параметр "Параметр". Для того что бы в метод этот параметр был передан надо добавить его в дереве метаданных. Для этого щелкните правой кнопкой по веб-операции Plus2 и выберите "Добавить-Параметр".
Реализация веб-сервиса в 1с
Давайте назовем его "Param". Названия параметров тоже можно указывать русскими, мало того  класс SoapClient языка PHP работает с ними корректно, ведь параметры передаются через массив. Желательно использовать кодировку UTF-8.

Укажем "Тип значения" int из пространства имен "http://www.w3.org/2001/XMLSchema".

Свойство "Возможно пустое" указывает что можно передать значение null в веб-операцию.

"Направление передачи" указывает по значению или по "ссылке" передается операнд в ws-операцию. Возможные значение "Входной", "Выходной", "Входной-Выходной". Таким образом если вы для параметра укажете "Выходной" или "Входной-Выходной" то сможете менять значения операнда. В результате xml сообщение-ответ дополнится строкой с новым значением операнда. Я пока не сталкивался с задачами которые можно решить только используя Выходное направление операнда, потому не могу дать какие то комментарии по этому свойству.

Вот в принципе и всё! Веб сервис создан, но существует он пока что только как описание в вашей конфигурации. Для того что бы им воспользоваться надо его опубликовать на вашем веб-сервере. Как опубликовать вы можете прочитать в статье 1С:Предприятие 8. Веб-сервисы. Публикация и тестирование.

32 комментария:

  1. Очень полезная и интересная статья. Автор - молодец!

    ОтветитьУдалить
  2. Даже для меня, начинающего программиста, все очень просто и понятно:)

    ОтветитьУдалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
  4. Не могли бы Вы подсказать как бороться с ошибками вида: "SoapFault exception: [soap:Client] Неизвестная ошибка. Процедура или функция с указанным именем не определена (ВвестиДату)"
    Может необходимы ли какие-то дополнительные права для пользователя, через которого работает веб-сервис??

    ОтветитьУдалить
    Ответы
    1. Ошибка содержит информацию в каком модуле и в какой строке она произошла. Например:

      {(1)}: Ошибка при вызове метода контекста (QuestionData)
      Результат = WSПрокси.QuestionData("");
      по причине:
      Ошибка вызова операции сервиса: {http://test.test.ru}:WebServices:QuestionData()
      по причине:
      Ошибка SOAP сервера: Неизвестная ошибка. {WebСервис.WebServices.Модуль(4209)}: Поле объекта не обнаружено (СписокВариантовОтветов)

      Это значит в строке 4209 веб сервиса имеется ошибка.

      В вашем случае вы используете функцию ВвестиДату() которая не может быть использована в веб-сервисе т.к. выполняет интерактивные действия.

      Если бы была проблема с правами то текст ошибки содержал слова "недостаточно прав".

      Удалить
    2. Огромное спасибо за ответ. Теперь проблема понятна.

      Удалить
  5. Этот комментарий был удален автором.

    ОтветитьУдалить
  6. Анонимный15 июля, 2013 20:54

    Добрый день.
    Подскажите
    Ошибка вызова операции сервиса: {localhost}:Catalog_Services:GetAllCars()
    по причине:
    Ошибка SOAP сервера: Неизвестная ошибка. Ошибка разбора XML: - [1,1]
    Фатальная ошибка:
    Extra content at the end of the document

    Может возникнуть если Пространство имен = localhost?

    ОтветитьУдалить
    Ответы
    1. Скорее всего нет. Вроде такая ошибка возникает если вы указали тип возвращаемого значения ws-операции, а потом этот тип в пакете XDTO переименовали. В итоге в пакете одно имя, а в имени результата возвращаемого значения другое имя. Проверить что все имена типов верные и пространство имен одинаковые.

      Удалить
    2. Анонимный16 июля, 2013 13:18

      Спасибо. Проверю

      Удалить
  7. Анонимный29 июля, 2013 15:30

    Добрый день, подскажите что может быть не так, сначала все работало отлично потом такая ошибка начала выпадать:
    Ошибка вызова операции сервиса: {urn:sap-com:document:sap:soap:functions:mc-style}:ZHR_INTEGR_D20CB_GET_EMPLOYEE:ZhrIntegrD20cbGetEmployee()
    по причине:
    Ошибка SOAP сервера: Dynamic function call failed

    ОтветитьУдалить
    Ответы
    1. Судя по тексту сообщения у вас 1с вызывает какую то функцию другой ИС и скорее всего проблема на их стороне. Но в чем именно проблема я сказать не могу

      Удалить
    2. Анонимный29 июля, 2013 15:55

      Большое спасибо за подсказку.

      Удалить
  8. Добрый день, кажется сервер глюкнул, не уверен, что предыдущая публикация дошла до сервера. У меня тут такая загвоздка вышла, есть два идентичных ws-сервеса, один работает на мобильные приложения, другой для удаленных серверов (синхронизация). Сервис для мобильного работает на ура, а вот сервис для удал.серверов выдает ошибку: Ошибка вызова операции сервиса: {http://localhost/ws/ws2}:Synchronization:ПолучитьДанные()
    по причине:
    Ошибка SOAP сервера: Неизвестная ошибка. bad allocation.
    Не подскажите ли Вы в чем может быть ошибка? Заранее благодарю

    ОтветитьУдалить
    Ответы
    1. Точнее, не слишком ли там сложный запрос из за чего может быть недостаток памяти?

      Удалить
  9. В общем то этот сервис предназначен для синхронизации двух одинаковых баз данных, но при первичной загрузке объем соответственно довольно-таки велик, не это ли является причиной возникновения данной ошибки?

    ОтветитьУдалить
  10. Спасибо, действительно все было в размере данных при синхронизации. Разбил на несколько отдельных пакетов и все заработало. еще раз спасибо за подсказку

    ОтветитьУдалить
  11. Если ругается при обращении к wsdl то скорее всего в WSDL есть несогласованность, например вы переименовали тип возвращаемого значения какой нибудь операции. А в самих типах не переименовали. Сам WSDL я не вижу, там логин и пароль требуется

    ОтветитьУдалить
  12. Добрый день.
    Помогите найти ответ на следующую проблему
    {ОбщаяФорма.Преобразование.Форма(55)}: Ошибка при вызове метода контекста (FullUp)
    Ответ = Десериализовать(Соединение.FullUp(СтрокаДанных));
    по причине:
    Ошибка вызова операции сервиса: {Shop}:Shop:FullUp()
    по причине:
    Неизвестная ошибка. Ошибка разбора XML: - [1,47]
    Фатальная ошибка:
    Space required after the Public Identifier

    по причине:
    Ошибка разбора XML: - [1,47]
    Фатальная ошибка:
    Space required after the Public Identifier

    ОтветитьУдалить
  13. Анонимный05 ноября, 2014 19:26

    Добрый день! есть задача связать 1С и программу документооборота. Программа документооборота будет дергать веб сервисы 1С, чтобы получать данные из справочников, добавлять записи в справочники...
    Возник такой вопрос: как по правильному нужно сделать: для каждого справочника отдельный веб-сервис, или в один веб-сервис все методы для всех справочников?
    Аналогично с XDTO, все типы в один ХДТО или в разные?
    Больше всего меня волнует вопрос по проблемам: если сломается/сломаю один веб-сервис, то сломается только один справочник, все остальное будет работать.
    Чем нужно руководствоваться, какими аргументами?
    Спасибо!

    ОтветитьУдалить
    Ответы
    1. Вероятность сломать полностью весь веб сервис есть. Например вы удалили тип из пакета а в выходном параметре операции не изменили. Тогда все сервисы не будут работать. Но я бы все равно посоветовал делать все операции в одном веб сервисе и все пакеты в одном пакете XDTO.
      В любом случае если у вас сломается веб сервис по заполнению номенклатуры, то нет смысла в заполнении допустим заказов на эту номенклатуры.

      Удалить
  14. Анонимный11 ноября, 2014 15:49

    Владимир! Добрый день!

    Есть такой вопрос: сделала веб-сервис в 1С, опубликовала, он работает в SoapUI, еще проверяли из других программ... Но нужно его использовать в программе, которая работает на платформе SharePoint. Так вот у них веб-сервис не работает. Как они объясняют: не тот синтаксис веб-сервиса.
    Вот как выглядит мой веб-сервис:

    А им нужно чтобы было так:


    Т.е. вместо "<xs:..." должно быть "<s:...".

    Как это сделать в 1С? Как изменить синтаксис опубликованного веб-сервиса?

    ОтветитьУдалить
    Ответы
    1. Анонимный11 ноября, 2014 15:52

      Не вставился текст веб сервиса.

      Вот такой синтаксис делает 1С:
      xs:schema targetNamespace=
      xs:element name=

      А вот так надо:
      s:schema elementFormDefault=
      s:element name=

      Почему 1С делает "xs", а не "s"?

      Удалить
  15. Анонимный14 марта, 2016 15:05

    Здравствуйте, подскажите пожалуйста, ошибка возвращаемое значение не понимает:

    Функция Pay(BIN, Kod, Summa, Tranzaction, Kolichestvo,Date)
    Справочники.ТранцакцияКИВИ.НайтиПоНаименованию(Tranzaction);
    // Если УникальныйКод = Справочники.ТранцакцияКИВИ.ПустаяСсылка() Тогда
    РегистрыСведений.ИсторияКонтрагентровДиллеров.СоздатьМенеджерЗаписи();



    МассивТоварыТип = ФабрикаXDTO.Тип("company.com/1C/Stroka", "Payment");
    МассивТовары = ФабрикаXDTO.Создать(МассивТоварыТип);
    Попытка
    /////Проверка, была ли уже такая транзакция из КИВИ
    УникальныйКод = Справочники.ТранцакцияКИВИ.НайтиПоНаименованию(Tranzaction);
    Если УникальныйКод = Справочники.ТранцакцияКИВИ.ПустаяСсылка() Тогда

    ///Создадим элемент для хранения Киви Транзакции
    ///Потом передаём код элемента на сайт
    УникальныйКод = Справочники.ТранцакцияКИВИ.СоздатьЭлемент();
    УникальныйКод.Наименование = Tranzaction;
    УникальныйКод.Записать();
    УникальныйКод = УникальныйКод.Ссылка;
    //////*************************************************
    Код = Справочники.СоответствиеКодов.НайтиПоНаименованию(Kod);
    ПромежуточнаяТаблица = РегистрыСведений.ИсторияКонтрагентровДиллеров.СоздатьМенеджерЗаписи();
    ПромежуточнаяТаблица.БИН = BIN;
    ПромежуточнаяТаблица.ДатаАктивации = Date;


    ПромежуточнаяТаблица.Период = ТекущаяДата();
    ПромежуточнаяТаблица.СоответствиеКодов = Код;
    ПромежуточнаяТаблица.Сумма = Summa;
    ПромежуточнаяТаблица.НомерТранзакции = УникальныйКод;
    ПромежуточнаяТаблица.СоздаватьСчёт = Истина;
    ПромежуточнаяТаблица.Количество = Kolichestvo;
    ПромежуточнаяТаблица.Записать();


    МассивТовары.BIN = BIN;
    МассивТовары.Tranzaction = УникальныйКод.Код;
    МассивТовары.Mistake = "ОК";


    Иначе
    МассивТовары.BIN = BIN;
    МассивТовары.Tranzaction = УникальныйКод.Код;
    МассивТовары.Mistake = "EXIST";


    КОнецЕсли;

    Исключение

    МассивТовары.BIN = BIN;
    МассивТовары.Tranzaction = -1;
    МассивТовары.Mistake = ОписаниеОшибки();

    КонецПопытки;


    Возврат МассивТовары;

    В чем может быть ошибка?

    ОтветитьУдалить
    Ответы
    1. Если МассивТовары действительно массив, то просто присвоить поля не правильно. Надо элемент массива создать сначала. Но это предположение. Вы лучше текст ошибки пришлите.

      Удалить
    2. Вот такая ошибка - Обязательное возвращаемое значение не задано: http://127.0.0.1}:PodpiskaSoapBinding:Pay()

      Удалить
    3. Вот такая ошибка - Обязательное возвращаемое значение не задано: http://127.0.0.1}:PodpiskaSoapBinding:Pay()

      Удалить
    4. Откройте пакет XDTO у полей есть два свойства: Минимальное количество и Возможно пустое. Если у поля минимальное количество > 0 то вы его должны в коде обязательно заполнить. Например МассивТовары.Tranzaction = -1; То есть если у типа Payment есть еще поле "Pole" то его тоже надо хоть чем то заполнить.

      Удалить
  16. адениум дома семена и взрослые адениумы

    Добавление материала

    разместить статью с активной ссылкой сайт с высоким ИКС

    ОтветитьУдалить