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

Программирование - Мобильные приложения

При выходе платформы 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
36
.cf 1 8,22Kb 36 Скачать
СерверHTTP
.cf 7,23Kb
26.09.16
35
.cf 1 7,23Kb 35 Скачать

См. также

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

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

при GET только через параметры запроса, пример: HTTPЗапрос( ИмяОпубликованнойБазы+ "/?geocode=1"); и принимаем на стороне сервера в Запрос.ПараметрыЗапроса
baracuda; +1 Ответить
12. kristart 80 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 80 13.07.16 22:46 Сейчас в теме
(13) alians-us, я думаю дело в том, что параметр не передается и дело именно в этом
Вы используете метод GET
Cоединение.Получить(HTTPЗапрос, Ответ);

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

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

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

либо заголовками, их можно установить вторым параметром при создании HTTPзапроса
либо используйте метод PUT, как и описано в статье
Cоединение.Записать(HTTPЗапрос, Ответ);
21. smirnovserg.s@gmail.com 25.09.16 14:42 Сейчас в теме
(14) извиняюсь, а в чем смысл указывать второй параметр Ответ в строке:

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


сервис работает и без него.
22. kristart 80 26.09.16 16:06 Сейчас в теме
(21) smirnovserg.s@gmail.com, спасибо за замечание, Вы правы, этот параметр не нужен для метода Записать (в статье исправил).
Его можно указывать используя метод Получить (GET-запрос) и тогда в ответ получим, как пишет синтаксис помощник - "Имя файла, в который помещаются данные полученного ресурса". В общем мы и так получаем все из HTTPОтвета, так что использование второго параметра, в нашем случае, считаю неоправданным.
17. sml 37 28.07.16 13:51 Сейчас в теме
Доброго дня, плюсанул за краткость и содержание, а также за комменты.
Есть вопрос: Если передавать данные через Заголовок (2й параметр запроса), то как его разбирать на стороне сервера?
18. kristart 80 28.07.16 18:28 Сейчас в теме
(17) sml, и Вам доброго дня.
заголовки это обычное соответствие.

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


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


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


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


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

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

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

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

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

В общем, Вам нужно указать логин и пароль при создании HTTP-соединения, примерно вот так:
Попытка
		Соединение = Новый HTTPСоединение(ПараметрыПодключения.АдресСервера,
		,ПараметрыПодключения.Пользователь,ПараметрыПодключения.Пароль,,Таймаут);
	Исключение
		//Сообщить("Не удалось установить соединение с сервером" 
		//+ Символы.ПС + ИнформацияОбОшибке().Описание, СтатусСообщения.Важное);
		ВызватьИсключение;
	КонецПопытки;
23. tindir 28.09.16 05:54 Сейчас в теме
Еще одна статья наколенного кода.
24. kristart 80 28.09.16 10:54 Сейчас в теме
(23) tindir, Доброго времени суток. Поясните пожалуйста что Вы имеете ввиду "наколенного кода"? Возможно стоит что-нибудь исправить или переписать?
user658391_zitri; +1 Ответить
25. TOSUNIK 15.06.17 17:42 Сейчас в теме
Оставьте свое сообщение