gifts2017

Простой пример передачи данных между клиентом и сервером через HTTP-сервисы

Опубликовал Вадим Хоменко (kristart) в раздел Программирование - Мобильные приложения

При выходе платформы 8.3.5 появилось желание переделать в уже готовом мобильном приложении соединение клиента с сервером из Web на HTTP-сервисы. В статье не будет кучи воды, только конкретная задача, все максимально просто.

При выходе платформы 8.3.5 появилось желание переделать в уже готовом мобильном приложении соединение клиента с сервером из Web на HTTP-сервисы. На то было много причин, и говорить о них в рамках этой статьи, думаю, будет неуместно.

Но когда казавшуюся тогда простую задачу я попробовал решить с помощью синтаксис помощника и мануала 1с тут и тут у меня возникла куча вопросов. И какое было мое удивление когда я нашел много примеров применения HTTP-сервисов, например здесь и здесь, но ни одного для моего случая.

В статье не будет кучи воды, только конкретная задача, все максимально просто.

Итак, поехали.

Для начала сделаем серверную часть.

Создаем новый HTTP-сервер. Назовем его, например Exchange, кореневой URL указываем такой же.

 

Далее переходим на вкладку ШаблоныURL. Добавляем новый шаблон, в моем случае Query, шаблон указываем /query/*.

 

Далее создаем метод и назовем его к примеру Action, HTTP-метод выбираем "Любой", жмем на кнопку с изображение лупы напротив поля "Обработчик" и автоматически создается функция.

 

В нее мы пишем следующее.

Функция QueryAction(Запрос)
      ПараметрыЗапроса = Запрос.ПолучитьТелоКакСтроку();
               
      Если ПараметрыЗапроса Тогда
           Ответ = "Информация с параметром";
      Иначе
           Ответ = "Информация без параметра";
      КонецЕсли;
                              
      HTTPОтвет = Новый HTTPСервисОтвет(200);
      HTTPОтвет.УстановитьТелоИзСтроки(Ответ);
      Возврат HTTPОтвет;
КонецФункции

Пробежавшись взглядрм сразу можно понять что для чего. В конце можно будет пробежать отладчиком и все сразу станет понятно и просто.

Публикуем базу и серверная часть готова.

Клиентская часть.

Для примера создадим общую форму. Добавляем в нее кнопку и пишем функцию которая отправит на сервер параметр и вернет нам результат.

Функция POSTЗапрос()
      Попытка
          //подключение к этому ПК
          Соединение = Новый HTTPСоединение("127.0.0.1");
      Исключение
          Возврат "Ошибка при создании HTTP соединения.";
      КонецПопытки;
               
      HTTPЗапрос = Новый HTTPЗапрос(ИмяОпубликованнойБазы+"/hs/Exchange/query");
      HTTPЗапрос.УстановитьТелоИзСтроки(ПараметрЗапроса);
               
      Ответ = "";
               
      Попытка
          HTTPОтвет =     Соединение.Записать(HTTPЗапрос);
          Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
      Исключение
          Возврат "Ошибка при соединении.";
      КонецПопытки;
               
      Возврат Ответ;
КонецФункции

ПарметрЗапроса в данном примере – Булево,

а ИмяОпубликованнойБазы – Строка (это то имя с которым проходила публикация на веб-сервере серверной части).

Вот и все примудрости.

Если нужно, можно скачать базы клиента и сервера, их прикрепляю ниже.

Ну вот, теперь-то я уверен, что если кому-то понадобиться переделать или сделать мобильное приложение с HTTP-сервисами, у него на одну головную боль будет меньше. Всем успехов! 

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
КлиентHTTP
.cf 8,22Kb
26.09.16
29
.cf 1 8,22Kb 29 Скачать
СерверHTTP
.cf 7,23Kb
26.09.16
31
.cf 1 7,23Kb 31 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. BigB (BigB) 15.03.15 01:57
(0) В двух файлах, для скачивания есть ещё, что нибудь кроме текстов, что вы выложили в описании?
2. Вадим Хоменко (kristart) 19.03.15 12:09
(1) BigB, только описанное в статье, запрос - ответ.
3. Александр Троицкий (Tasselhof) 28.09.15 18:15
Только вместо - Соединение.Записать(HTTPЗапрос, Ответ);
надо - Соединение.Получить(HTTPЗапрос, Ответ);
4. Вадим Хоменко (kristart) 05.10.15 22:04
(3) Tasselhof, согласен, так тоже выглядит хорошо. Но в данном примере, HTTP-метод = любой, поэтому разницы нет.
5. Игорь Яровенко (FireFox_Manager) 13.11.15 16:27
Плюсанул за то, что автор кратко и доступно изложил суть вопроса и привел работающий код.
6. Андрей Краснокутский (Andry.Boris) 07.12.15 15:29
Автору +
Скачал, попробовал по вашей схеме, работает,
проверил и с мобильного телефона, тоже все отлично отрабатывает.
Главное коротко и понятно.
7. Вася Пупкин (bubus) 18.12.15 00:37
А как передать файл HTTP сервису в 1с?
8. Вадим Хоменко (kristart) 18.12.15 14:00
(7) bubus, Можно сериализовать данные и передать сериализованную строку (если ее еще и сжать, поместив в хранилище - пакет меньше будет). Про сериализацию почитать можно например тут или просто в гугл вбить, примеров много.
9. Вася Пупкин (bubus) 18.12.15 14:54
(8) kristart, спс уже сделал. Но вот про сжатие не знал. Отправляю в xml-двоичные-base64, а в http сервисе в обратном порядке, из мобильного приложения. Единственное что не нашел примера с методом PUT для HTTP сервиса. И еще вопрос, вы не знаете какой размер максимально можно приатачить к запросу? Понятно отрубит по таймауту, но есть ли ограничения по размерам? Где то читал про передаче через HTTP соединение из моб. приложения максимум 80кб. Типо баг что ли такой вроде был.
10. Вадим Хоменко (kristart) 19.12.15 14:40
(9) bubus, у меня небыло проблем с размерами файлов. В основном передавал файлы размером до 100мб - было все ок.
11. Александр Маликов (malikov_pro) 12.04.16 00:26
Автор немного "срезал", и при Соединение.Получить серверная сторона работать будет некорректно

при POST тело сообщения передается и конструкция УстановитьТелоИзСтроки(ПараметрЗапроса) -> Запрос.ПолучитьТелоКакСтроку() работает

при GET только через параметры запроса, пример: HTTPЗапрос( ИмяОпубликованнойБазы+ "/?geocode=1"); и принимаем на стороне сервера в Запрос.ПараметрыЗапроса
12. Вадим Хоменко (kristart) 23.04.16 23:17
(11) malikov_pro, хороший коммент, как Вы правильно указали я "срезал" все уточнения и много теории. Дело в том, что я хотел показать самый минимум. Все как для новичка, которому просто надо запустить сервис, а разбираться со временем.

Кстати, некоторые параметры я сериализовал и передавал в заголовках (как строку). Еще один вариант прицепить данные.
13. Дмитрий Сергеев (alians-us) 13.07.16 17:56
у меня есть код
&НаСервере

Функция POSTЗапрос()
ПараметрЗапроса=истина;	
      Попытка
          //подключение к этому ПК
          Соединение = Новый HTTPСоединение("127.0.0.1");
      Исключение
          Возврат "Ошибка при создании HTTP соединения.";
      КонецПопытки;
               
      HTTPЗапрос = Новый HTTPЗапрос("Opoveshatel_android/hs/Exchange/query");
      HTTPЗапрос.УстановитьТелоИзСтроки(ПараметрЗапроса);
               
      Ответ = "";
               
      Попытка
          HTTPОтвет =     Соединение.Получить(HTTPЗапрос, Ответ);
          Ответ = HTTPОтвет.ПолучитьТелоКакСтроку();
      Исключение
          Возврат "Ошибка при соединении.";
      КонецПопытки;
               
      Возврат Ответ;
  КонецФункции

&Наклиенте
Процедура Команда1(Команда)

Сообщить(POSTЗапрос());
  КонецПроцедуры
...Показать Скрыть

после нажатия на кнопку просто сообщает пустой ответ
14. Вадим Хоменко (kristart) 13.07.16 22:46
(13) alians-us, я думаю дело в том, что параметр не передается и дело именно в этом
Вы используете метод GET
Cоединение.Получить(HTTPЗапрос, Ответ);

соответственно тело не передается
HTTPЗапрос.УстановитьТелоИзСтроки(ПараметрЗапроса);

нужно устанавливать параметры как писал malikov_pro:
"при GET только через параметры запроса, пример:
HTTPЗапрос( ИмяОпубликованнойБазы+ "/?geocode=1");

и принимаем на стороне сервера в Запрос.ПараметрыЗапроса

либо заголовками, их можно установить вторым параметром при создании HTTPзапроса
либо используйте метод PUT, как и описано в статье
Cоединение.Записать(HTTPЗапрос, Ответ);
15. Илья Низамов (Region102) 27.07.16 14:41
(8) kristart, мне интересно как вы поместите ХранилищеЗначения в тело http запроса.
16. Вадим Хоменко (kristart) 27.07.16 19:28
(15) Region102, все проще чем кажется.
Сериализуем необходимые данные и на выходе получаем строку которую и помещаем в тело.
На принимающей стороне десериализуем и вуалая! - вот они наши данные.
Соответственно передать можно все что сериализуется (посмотреть это свойство объекта можно в синтаксис помощнике).
ХранилищеЗначения - сериализуется, то есть его так же можно передать в теле.
17. Олег Веселов (sml) 28.07.16 13:51
Доброго дня, плюсанул за краткость и содержание, а также за комменты.
Есть вопрос: Если передавать данные через Заголовок (2й параметр запроса), то как его разбирать на стороне сервера?
18. Вадим Хоменко (kristart) 28.07.16 18:28
(17) sml, и Вам доброго дня.
заголовки это обычное соответствие.

На стороне сервера предположим есть принимающая функция
Функция RegistrationChek(Запрос)


Вот что мы получим


Я передал два параметра поместив их в заголовки:
Соответствие = Новый Соответствие();
	Соответствие.Вставить("ТипОбращения", ПараметрыПодключения.ТипОбращения);
	Соответствие.Вставить("ПакетОбмена",ПараметрыПодключения.ИсходящееСообщение);
	HTTPЗапрос = Новый HTTPЗапрос(ПараметрыПодключения.РесурсНаСервере+ "/?geocode=1",Соответствие);


И вот они на сервере


А потом уже обращаемся к своим параметра как хотим,
можно так
Запрос.Заголовки["ПакетОбмена"]

или так
Запрос.Заголовки.Получить("ПакетОбмена")

в общем как удобно.
19. serko krav (serko8547) 26.08.16 17:19
Ув. Автор, прошу Вас поделиться опытом:
Я начал использовать http-сервисами недавно, и напоролся на такую проблему: Если в 1с завести пользователя - то мне ответ на любой Get или post запрос приходит Ошибка 401 (не авторизован). Как быть?
Был бы Вам очень благодарен, если Вы подскажете, как решить сию проблему )

авторизация в смысле запросом логина-пароли - программно, т.е. я не ручками ввожу логин-пароль, а как мне авторизоваться программно.
20. Вадим Хоменко (kristart) 27.08.16 15:17
(19) serko8547, Приветствую.

Если нет пользователя, авторизационные данные в HTTP-соединении указывать не обязательно; даже в базу пускает не запрашивая логин (без авторизации).
Как только Вы завели пользователя - авторизация обязательна и при попытке войти в базу система будет запрашивать логин и пароль.

В общем, Вам нужно указать логин и пароль при создании HTTP-соединения, примерно вот так:
Попытка
		Соединение = Новый HTTPСоединение(ПараметрыПодключения.АдресСервера,
		,ПараметрыПодключения.Пользователь,ПараметрыПодключения.Пароль,,Таймаут);
	Исключение
		//Сообщить("Не удалось установить соединение с сервером" 
		//+ Символы.ПС + ИнформацияОбОшибке().Описание, СтатусСообщения.Важное);
		ВызватьИсключение;
	КонецПопытки;
...Показать Скрыть
21. Sergey S (smirnovserg.s@gmail.com) 25.09.16 14:42
(14) kristart, извиняюсь, а в чем смысл указывать второй параметр Ответ в строке:

HTTPОтвет =     Соединение.Записать(HTTPЗапрос, Ответ);


сервис работает и без него.
22. Вадим Хоменко (kristart) 26.09.16 16:06
(21) smirnovserg.s@gmail.com, спасибо за замечание, Вы правы, этот параметр не нужен для метода Записать (в статье исправил).
Его можно указывать используя метод Получить (GET-запрос) и тогда в ответ получим, как пишет синтаксис помощник - "Имя файла, в который помещаются данные полученного ресурса". В общем мы и так получаем все из HTTPОтвета, так что использование второго параметра, в нашем случае, считаю неоправданным.
23. Tindir Mindir (tindir) 28.09.16 05:54
Еще одна статья наколенного кода.
24. Вадим Хоменко (kristart) 28.09.16 10:54
(23) tindir, Доброго времени суток. Поясните пожалуйста что Вы имеете ввиду "наколенного кода"? Возможно стоит что-нибудь исправить или переписать?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа