JSON отправка данных

1. user1786138 09.04.24 16:46 Сейчас в теме
Столкнулся с проблемой, нужно из данных сформировать структуру JSON и отправить во ФГИС
УТКО:

Что нужно прописать, чтобы данные отправились и пришел ответ? Либо подробно пошагово объяснить что мне нужно сделать, чтобы решить задачу. Заранее всех благодарю

Получив ключ доступа, можно воспользоваться сервисом для передачи ФГИС
УТКО:
curl -X 'POST' \
'https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import' \
-H 'accept: */*' \
-H 'Content-Ty+

После обработки данных ФГИС УТКО возвращает ответ внешней системе. Список
кодов с ответами при взаимодействии описан
200 - Запрос успешно обработан
403 - Ограничение в доступе. Некорректный ключ доступа
422 - Ошибка валидации
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. starik-2005 3087 09.04.24 17:55 Сейчас в теме
С = Новый ХТТПСоединение(сервер, порт, юзер, пассворд, таймаут, новый ЗащищенноеСоединениеССЛ());
З = Новый ХТТПЗапрос(Урл);
З.УстановитьТелоИзСтроки(ДжиСон);
Ответ = С.ОтправитьДляОбработки(З);
Если Ответ.КодОтвета = 200 Тогда
  Сообщить("Зебест, все ништяк!")
Иначе
  Сообщить("Все плохо, код ошбки в ответе");
КонецЕслей
// бла-бла-ба
Показать
3. user1786138 10.04.24 12:22 Сейчас в теме
(2) Наверно я не правильно описал проблему.
Получив ключ доступа, можно воспользоваться сервисом для передачи ФГИС
УТКО:
curl -X 'POST' \
'https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'file='
Где file - файл с данными весового контроля.
Вот такой пример я составил по структуре JSON.

// Создать структуру с данными.
Данные = Новый Структура;
Данные.Вставить("objectId", "ce0dec40-5f72-447c-9d5e-abe4bebffdaa");
Данные.Вставить("accessKey", "c876210a-ccec-454d-8b1d-6d5064a8d109");

// Добавить элемент структуры МассивВесы типа Массив.
МассивВесы = Новый Массив;

ДанныеВН = Новый Структура;
ДанныеВН.Вставить("id","c944a08b-61c8-4d33-a0f4-61b235ae9bb9");
ДанныеВН.Вставить("dateBefore", "2022-01-28 08:11:31.897387");
ДанныеВН.Вставить("dateAfter", "2022-01-28 08:41:31.897387");
ДанныеВН.Вставить("registrationNumber", "к332пп777");
ДанныеВН.Вставить("garbageTruckType", "Самосвал");
ДанныеВН.Вставить("garbageTruckBrand", "ГАЗ");
ДанныеВН.Вставить("garbageTruckModel", "КО-440-2");
ДанныеВН.Вставить("companyName", "ООО СПЕКТР");
ДанныеВН.Вставить( "companyInn", "0275905660");
ДанныеВН.Вставить("companyKpp", "862201001");
ДанныеВН.Вставить("weightBefore", "23120");
ДанныеВН.Вставить( "weightAfter", "13850");
ДанныеВН.Вставить( "weightDriver", "80");
ДанныеВН.Вставить("coefficient", "1");
ДанныеВН.Вставить("garbageWeight", "9190");
ДанныеВН.Вставить("garbageType", "Производственный мусор");
ДанныеВН.Вставить("codeFKKO", "2 21 000 00 00 0");
ДанныеВН.Вставить("nameFKKO", "Отходы добычи и обогащения железных руд");

МассивВесы.Добавить(ДанныеВН);


Данные.Вставить("weightControls", МассивВесы);


// Создать объект записи и открыть файл, в который будет выполняться запись.
Запись = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб);
Запись.ОткрытьФайл("C:\Users\dkukushkin\Desktop\Тест Json\Test.json",,, ПараметрыЗаписиJSON);
// Выполнить запись данных (Данные) с помощью объекта записи (Запись).
ЗаписатьJSON(Запись, Данные);

// Завершить работу с файлом.
Запись.Закрыть();

Теперь мне нужно отправить данные и получить ответ. Прошу помочь и описать шаги работы. Спасибо заранее
Прикрепленные файлы:
Инструкция_для_подключения_интеграции_по_весовому_контролю.pdf
4. oliaYun 07.11.24 14:50 Сейчас в теме
(3) Здравствуйте, как вы решили вопрос? У меня не получается отправить к ним запрос, приходит ошибка валидации.
5. user1671936 1 08.11.24 16:56 Сейчас в теме
(4) покажите запрос, который отправляете, и ошибку, которая приходит
17. DimanZ 27 11.11.24 11:01 Сейчас в теме
(3) Добрый день.
Аналогичная oliaYun ошибка 422.
Подскажите как решили вопрос.
18. DimanZ 27 11.11.24 11:18 Сейчас в теме
(3) Запрос такой
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.reo.ru", , , , , , ЗащищенноеСоединение);
Запрос = Новый HTTPЗапрос("reo-weight-control-api/api/v1/weight-controls/import");

Запрос.Заголовки.Вставить("accept", "*/*");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data");
Запрос.УстановитьИмяФайлаТела("D:\Test.json");

Ответ = Соединение.ОтправитьДляОбработки(Запрос);
20. starik-2005 3087 11.11.24 11:21 Сейчас в теме
(18)
Запрос.УстановитьИмяФайлаТела("D:\Test.json");
Я хз, но у 1С это не работает.
22. DimanZ 27 11.11.24 14:50 Сейчас в теме
(20) Посмотрел через Запрос.ПолучитьТелоКакСтроку();
Ну там внутренности файла как раз присутствуют...
6. DimanZ 27 11.11.24 08:03 Сейчас в теме
Доброго времени суток, коллеги.
Делаю так, приходит код ответа 301

Соединение = Новый HTTPСоединение("api.reo.ru");
Запрос = Новый HTTPЗапрос("https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import");

Запрос.Заголовки.Вставить("accept", "*/*");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data");
Запрос.УстановитьИмяФайлаТела("D:\Test.json");

Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Подскажите, если решили
7. user1863362 11.11.24 08:20 Сейчас в теме
(6)
Подскажите, если решили
Конечно! Вот фрагмент из документации, который описывает этот случай:

On the World Wide Web, HTTP 301 is the HTTP response status code for 301 Moved Permanently. It is used for permanent redirecting, meaning that links or records returning this response should be updated. The new URL should be provided in the Location field, included with the response. The 301 redirect is considered a best practice for upgrading users from HTTP to HTTPS.

RFC 2616[1] states that:
* If a client has link-editing capabilities, it should update all references to the Request URL.
* The response is cacheable unless indicated otherwise.
* Unless the request method was HEAD, the entity should contain a small hypertext note with a hyperlink to the new URL(s).
* If the 301 status code is received in response to a request of any type other than GET or HEAD, the client must ask the user before redirecting.
10. DimanZ 27 11.11.24 09:10 Сейчас в теме
(7) В ответе приходит Location "https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import"
Прописываю в HTTPЗапрос, не помогает
8. laperuz 47 11.11.24 08:52 Сейчас в теме
(6) В HTTPЗапрос домен не нужен
9. DimanZ 27 11.11.24 09:09 Сейчас в теме
(8) Что с доменом, что без, ответ одинаков - 301
В ответе приходит Location "https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import"
11. DimanZ 27 11.11.24 09:16 Сейчас в теме
Вероятно что-то с SSL

Если так, то ошибка 422 (ошибка валидации)

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто),
Новый СертификатыУдостоверяющихЦентровWindows());

Соединение = Новый HTTPСоединение("api.reo.ru", , , , , , ЗащищенноеСоединение);

Запрос = Новый HTTPЗапрос("reo-weight-control-api/api/v1/weight-controls/import");

Запрос.Заголовки.Вставить("accept", "*/*");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data");
Запрос.УстановитьИмяФайлаТела("D:\Test.json");
12. user1863362 11.11.24 09:34 Сейчас в теме
(11) А у тебя реально используется авторизация клиента сертификатом или ты просто от балды код пишешь?
13. DimanZ 27 11.11.24 09:41 Сейчас в теме
(12) От балды вероятно - вообще не изучал тему, но если без ЗащищенноеСоединение , то 301 получаю, а с ЗащищенноеСоединение уже хоть что-то

В мануале написано нужно так:
curl -X 'POST' \
'https://api.reo.ru/reo-weight-control-api/api/v1/weight-controls/import' \
-H 'accept: */*' \
-H 'Content-Type: multipart/form-data' \
-F 'file='
Где file - файл с данными весового контроля, см. Таблица 1
14. user1863362 11.11.24 10:10 Сейчас в теме
(13)
В мануале написано

Если я правильно помню, что означает курловое -F ''file=', то должно быть примерно так:

	СодержимоеJSON = "...";
	
	ИмяПараметра = "file";
	ТипMime = "application/json";
	
	Граница = СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
	
	Поток = Новый ПотокВПамяти;
	Запись = Новый ЗаписьДанных(Поток, "UTF-8", , Символы.ВК + Символы.ПС);
	
	Запись.ЗаписатьСтроку(СтрШаблон("--%1", Граница);
	Запись.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=""%1""", ИмяПараметра);
	Запись.ЗаписатьСтроку(СтрШаблон("Content-Type: %1", ТипMime);
	Запись.ЗаписатьСтроку("");
	Запись.ЗаписатьСтроку(СодержимоеJSON);
	Запись.ЗаписатьСтроку(СтрШаблон("--%1--", Граница);
	Запись.ЗаписатьСтроку("");
	Запись.Закрыть();
	
	ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
	Соединение = Новый HTTPСоединение("api.reo.ru", , , , , ,ЗащищенноеСоединение);
	
	Запрос = Новый HTTPЗапрос("reo-weight-control-api/api/v1/weight-controls/import");
	Запрос.Заголовки.Вставить("accept", "*/*");
	Запрос.Заголовки.Вставить("Content-Type", СтрШаблон("multipart/form-data; boundary=%1", Граница));
	
	ТелоЗапроса = Поток.ЗакрытьИПолучитьДвоичныеДанные();
	Запрос.УстановитьТелоИзДвоичныхДанных(ТелоЗапроса);
	
	Ответ = Соединение.ОтправитьДляОбработки(Запрос); 
Показать
15. DimanZ 27 11.11.24 10:15 Сейчас в теме
(14) Спасибо!
Попробую так.
16. DimanZ 27 11.11.24 10:59 Сейчас в теме
(14) Те же грабли (
Кажется у автора темы получилось
19. starik-2005 3087 11.11.24 11:20 Сейчас в теме
(16)
		Соединение = Новый HTTPСоединение("www.service.xxx", , , , , Таймаут, Новый ЗащищенноеСоединениеOpenSSL(), Ложь);
		Заголовки = Новый Соответствие;
		Заголовки["accept"] = "application/json";
		Заголовки["Content-Type"] = "multipart/form-data; boundary=----WebKitFormBoundary" + IDBoundary;

		Запрос = Новый HTTPЗапрос("/api/v1/blabla", Заголовки);

		data = ПолучитьЧертовJSON();

		Запрос.УстановитьТелоИзСтроки(
			"------WebKitFormBoundary" + IDBoundary + "
			|Content-Disposition: form-data; name=""data""
			|
			|" + data + "
			|------WebKitFormBoundary" + IDBoundary + "--");

		Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Показать
21. DimanZ 27 11.11.24 14:46 Сейчас в теме
(19)
Ответ сервера
{"":["Failed to read the request form. Missing content-type boundary."]}

Поправил в запросе WebKitFormBoundary60b7addaa04b4f8d9609577e58f8c807 - пробел сделал

Так, уже ближе - Ответ {"file":["The file field is required."]}

В теле запроса такое
------WebKitFormBoundary60b7addaa04b4f8d9609577e58f8c807
Content-Disposition: form-data; name="data"

{"objectId":"0f62b963-a***","accessKey":"***-a7d9-47961cd636ef","weightControls":[{"id":"058a901f-099c-4411-9971-b60022247fec","dateBefore":"2022-01-28 10:08:16.497247+03:00","dateAfter":"2022-01-28 10:52:31.897387+03:00","registrationNumber":"о145нн33","garbageTruckType":"Самосвал","garbageTruckBrand":"ГАЗ","garbageTruckModel":"КО-440-2","companyName":"ООО СПЕКТР","companyInn":"0275905660","companyKpp":"862201001","weightBefore":"24580","weightAfter":"10242","weightDriver":"95","coefficient":"1","garbageWeight":"14243","garbageType":"Производственный мусор","codeFKKO":"2 21 000 00 00 0","nameFKKO":"Отходы добычи и обогащения железных руд"}]}
------WebKitFormBoundary60b7addaa04b4f8d9609577e58f8c807--
23. starik-2005 3087 11.11.24 16:09 Сейчас в теме
(21)
{"file":["The file field is required."]}
Ну так слово data на слово file поменяй.
25. DimanZ 27 11.11.24 16:27 Сейчас в теме
(23) Ну так менял, ясен перец )
26. Sashares 35 11.11.24 16:28 Сейчас в теме
(25)
В теле запроса такое
------WebKitFormBoundary60b7addaa04b4f8d9609577e58f8c807
Content-Disposition: form-data; name="data"

Заметно)
27. DimanZ 27 11.11.24 16:31 Сейчас в теме
(26) Если все попытки сюда копипастить, простыня большая будет )
------WebKitFormBoundary 11f33499f0b1443f92b747b8f891ec2d
Content-Disposition: form-data; name="file"

{"objectId":"****9d-f0b9872141a8","accessKey":"*****4d72-a7d9-47961cd636ef","weightControls":[{"id":"058a901f-099c-4411-9971-b60022247fec","dateBefore":"2022-01-28 10:08:16.497247+03:00","dateAfter":"2022-01-28 10:52:31.897387+03:00","registrationNumber":"о145нн33","garbageTruckType":"Самосвал","garbageTruckBrand":"ГАЗ","garbageTruckModel":"КО-440-2","companyName":"ООО СПЕКТР","companyInn":"0275905660","companyKpp":"862201001","weightBefore":"24580","weightAfter":"10242","weightDriver":"95","coefficient":"1","garbageWeight":"14243","garbageType":"Производственный мусор","codeFKKO":"2 21 000 00 00 0","nameFKKO":"Отходы добычи и обогащения железных руд"}]}
------WebKitFormBoundary 11f33499f0b1443f92b747b8f891ec2d
28. Sashares 35 11.11.24 16:44 Сейчас в теме
(27) И какая ошибка в этом случае?
29. DimanZ 27 11.11.24 16:56 Сейчас в теме
(28) Если после -----WebKitFormBoundary пробел, то ошибка {"file":["The file field is required."]}
Если без пробела то {"":["Failed to read the request form. Unexpected end of Stream, the content may have already been read by another component. "]}

Вот тут ниже вариант, полученный с двоичных данных файла - (24)
{"":["Failed to read the request form. Invalid header line: \r"]}
35. DimanZ 27 11.11.24 19:27 Сейчас в теме
(23) Благодарю за участие!
24. DimanZ 27 11.11.24 16:23 Сейчас в теме
(14) Ответ сервера {"":["Failed to read the request form. Invalid header line: \r"]}
Тело запроса такое
--69a8718dfa1b46bab90f2aac8ecb515f
Content-Disposition: form-data; name="file"
Content-Type: application/json

{"objectId":"******9d-f0b9872141a8","accessKey":"*******7d9-47961cd636ef","weightControls":[{"id":"058a901f-099c-4411-9971-b60022247fec","dateBefore":"2022-01-28 10:08:16.497247+03:00","dateAfter":"2022-01-28 10:52:31.897387+03:00","registrationNumber":"о145нн33","garbageTruckType":"Самосвал","garbageTruckBrand":"ГАЗ","garbageTruckModel":"КО-440-2","companyName":"ООО СПЕКТР","companyInn":"0275905660","companyKpp":"862201001","weightBefore":"24580","weightAfter":"10242","weightDriver":"95","coefficient":"1","garbageWeight":"14243","garbageType":"Производственный мусор","codeFKKO":"2 21 000 00 00 0","nameFKKO":"Отходы добычи и обогащения железных руд"}]}
--69a8718dfa1b46bab90f2aac8ecb515f--
30. Sashares 35 11.11.24 17:01 Сейчас в теме
(24) (27) Рабочий пример передачи присоединенного файла из двоичных данных в другой сервис.
Но смысл понятен:
ДД = ПолучитьИзВременногоХранилища(Данныефайла.СсылкаНаДвоичныеДанныеФайла);
	
	Разделитель = "----"+СтрЗаменить(Строка(Новый УникальныйИдентификатор),"-","");
	
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
	
	Запрос = Новый HTTPЗапрос(СтруктураАдреса.ПутьНаСервере,Заголовки);
	
	Тело = Новый ПотокВПамяти();

	ЗаписьДанных = Новый ЗаписьДанных(Тело, , , Символы.ВК + Символы.ПС, "");   

	ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);   	 

	ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename="""+СокрЛП(Данныефайла.ИмяФайла)+"""");
	ЗаписьДанных.ЗаписатьСтроку("");
	ЗаписьДанных.Записать(ДД);
	ЗаписьДанных.ЗаписатьСтроку("");
	ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель+"--");
	ЗаписьДанных.ЗаписатьСтроку("");
	ЗаписьДанных.Закрыть();
	
	ДанныеТела = Тело.ЗакрытьИПолучитьДвоичныеДанные();
	Запрос.УстановитьТелоИзДвоичныхДанных(ДанныеТела);
Показать


Запись пустой строки нужна, удалять их не надо.
31. DimanZ 27 11.11.24 17:45 Сейчас в теме
(30) Вероятно мы близки к чему-то. Ответ сервера - пустая строка, КодСостояния 415
Хотя пишут в тырнете HTTP 415 Unsupported Media Type
Тело запроса такое (если см Запрос.ПолучитьТелоКакСтроку())

-----2d4d698c6bf54f14b78abaa69efddb22
Content-Disposition: form-data; name="file"; filename="D:\Test.json"

{
"objectId": "****47c-9d5e-abe4bebffdaa",
"accessKey": *****c-454d-8b1d-6d5064a8d109",
"weightControls": [
{
"id": "058a901f-099c-4411-9971-b60022247fec",
"dateBefore": "2022-01-28 10:08:16.497247+03:00",
"dateAfter": "2022-01-28 10:52:31.897387+03:00",
"registrationNumber": "о145нн33",
"garbageTruckType": "Самосвал",
"garbageTruckBrand": "ГАЗ",
"garbageTruckModel": "КО-440-2",
"companyName": "ООО СПЕКТР",
"companyInn": "0275905660",
"companyKpp": "862201001",
"weightBefore": "24580",
"weightAfter": "10242",
"weightDriver": "95",
"coefficient": "1",
"garbageWeight": "14243",
"garbageType": "Производственный мусор",
"codeFKKO": "2 21 000 00 00 0",
"nameFKKO": "Отходы добычи и обогащения железных руд"
}
]
}

------2d4d698c6bf54f14b78abaa69efddb22--
32. Sashares 35 11.11.24 18:16 Сейчас в теме
(31)
; filename="D:\Test.json"

лишнее
33. DimanZ 27 11.11.24 19:24 Сейчас в теме
(32) Нет, не лишнее.
Извиняюсь - по запарке Заголовки HTTPЗапрос не заполнил и получал 415.

Все работает!! Огромная благодарность!
37. Sashares 35 12.11.24 11:37 Сейчас в теме
(33) Если вы указываете filename, то не стоит в нем указывать полный путь. Это имя загружаемого файла. То есть в данном случае "Test.json".
38. DimanZ 27 12.11.24 12:01 Сейчас в теме
(37) Да, так и сделал. Не понимаю зачем вообще оно нужно.
Сейчас допилил без записи json временного файла на диск. Работает.

Запись = Новый ЗаписьJSON;
	ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб);
	Запись.УстановитьСтроку(); //  <Параметры> (необязательный) Тип: ПараметрыЗаписиJSON. 
	ЗаписатьJSON(Запись, Данные); 
	// Завершить работу с файлом.
	ДанныеJS = Запись.Закрыть(); 
	ДД = ПолучитьДвоичныеДанныеИзСтроки(ДанныеJS )

Сервис благополучно кушает с кодом 200, но на портале не появляются данные. Причем кушает и с отвесами за предыдущие даты, и 100/500 раз за сегодня отправил...

Звонил в ТП, жду ответ.
34. DimanZ 27 11.11.24 19:26 Сейчас в теме
(14) Благодарю за участие!
36. DimanZ 27 12.11.24 10:10 Сейчас в теме
(14) Проверил с поправками - код под api ФГИС УТКО тоже рабочий.

Запись = Новый ЗаписьДанных(Поток, "UTF-8", , Символы.ВК + Символы.ПС,""); // тут добавил параметр КонвертируемыйРазделительСтрок = ""


и еще поправочка

можно так
Запись.ЗаписатьСтроку(СодержимоеJSON); // где СодержимоеJSON = СтрокаJSON 

или можно так
Запись.Записать(ДвоичныеДанныефайлаJSON);
Запись.ЗаписатьСтроку("");// если ДвоичныеДанные - обязательно добавляем пустую строку
Запись.ЗаписатьСтроку(СтрШаблон("--%1--", Граница);


Получаю код ответа 200, все норм.

Теперь непонятки когда данные должны появиться у них на портале, ТехПоддержка что-то там сложная
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот