Ошибка с кодом состояния 500 при отправке POST-запроса на регистрацию исходящего Акта приема-передачи по маркировке обуви

1. azamatagent 11.03.22 07:45 Сейчас в теме
Добрый день,

привожу код по формированию http-запроса на отправку исходящего Акта приема-передачи по маркировке:

content = ПолучитьДокументXMLПриОтправкеАкта(ДокументСсылка); // функция возвращает строку в виде XML Акта ПП 	
content = ПолучитьДвоичныеДанныеИзСтроки(content); 	
content = СтрЗаменить(СтрЗаменить(Base64Строка(content), Символы.ВК, ""), Символы.ПС,""); // Акт ПП в Base64
	
signature = СтруктураПараметров["ПолеDATA"]; // подпись ЭЦП 	
signature = ПолучитьДвоичныеДанныеИзСтроки(signature);
signature = СтрЗаменить(СтрЗаменить(Base64Строка(signature), Символы.ВК, ""), Символы.ПС,""); // подпись ЭЦП в Base64

// далее - формирование тела запроса в формате "multipart/form-data"
	
Разделитель = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
	
ТелоЗапроса = Новый ТекстовыйДокумент(); 	
ТелоЗапроса.РазделительСтрок = Символы.ВК + Символы.ПС;
ТелоЗапроса.ДобавитьСтроку("--" + Разделитель);
ТелоЗапроса.ДобавитьСтроку("Content-Disposition: form-data; name=""content"";");
ТелоЗапроса.ДобавитьСтроку("");
ТелоЗапроса.ДобавитьСтроку(content);	
ТелоЗапроса.ДобавитьСтроку("--" + Разделитель);
ТелоЗапроса.ДобавитьСтроку("");
ТелоЗапроса.ДобавитьСтроку("Content-Disposition: form-data; name=""signature"";");
ТелоЗапроса.ДобавитьСтроку("");
ТелоЗапроса.ДобавитьСтроку(signature);	
ТелоЗапроса.ДобавитьСтроку("");
ТелоЗапроса.ДобавитьСтроку("--" + Разделитель + "--");		
ТелоЗапроса = ТелоЗапроса.ПолучитьТекст();
		
АдресРесурса = "/api/v3/true-api/edo-api/outgoing-documents/formal";

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
Заголовки.Вставить("Authorization", СтрШаблон("Bearer %1", ТокенАкторизации)); // ТокенАвторизации - динамически получаемый параметр вида "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9........."

HTTPСоединение = Новый HTTPСоединение("stage.ismet.kz", 443, Неопределено, Неопределено, Неопределено, 0, Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено)); // "stage.ismet.kz" - тестовая ИС по маркировке
		
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);			
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
	
Попытка    
		
    HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
				
    ТекстОтвета = СокрЛП(HTTPОтвет.ПолучитьТелоКакСтроку());  
		
Исключение
	
КонецПопытки;  
Показать


В результате получаю ошибку с кодом состояния 500 {"error_message":"Ошибка при выполнении запроса"}. В Postman дается более подробный ответ:
{
"code": 500,
"description": "org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; ...................
"error_message": "Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found"
}

То есть, тело запроса некорректное?
Прикрепленные файлы:
Тело запроса в формате multipartform-data.txt
Ответы
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. vera_bo 07.02.23 16:07 Сейчас в теме
(1) Здравствуйте. Столкнулась точно с такой же проблемой.
Вам удалось в итоге справиться с ошибкой?
content формирую по описанию (kz) v.2.22 Описание работы с API (True-API).
signature - формирую через COM объект, через библиотеку KalkanCryptCOMLib, (подписываю с помощью сертификата методом SignData). И постоянно ошибки:
{"error_message":"Ошибка при выполнении запроса"} - когда отправляю также как у вас, с разделителями,
"Failed to parse multipart servlet request; nested exception is java.io.IOException" - когда отправляю в Postman,
"Required request part 'content' is not present......." когда отправляю без разделителей
3. azamatagent 08.02.23 06:39 Сейчас в теме
(2) Добрый день, да, получилось. Получил ответ от тех. поддержки:
4. azamatagent 08.02.23 06:40 Сейчас в теме
(3) Добрый день! На Вашу заявку пришло решение: Спасибо за обращение. При анализе файла «Скрипт в поле HTML документа 1С для получения ЭЦП в CMS» обнаружено что в поле «args: ["PKCS12", "SIGNATURE", xmlData, true]» у Вас указано значение «true». Прошу поменять значение «true» на «false» и повторно отправить запрос.
Обратите внимание, что значение «true» нужно применять только для метода получения токена методами API, а в остальных случаях применяется значение «false».
Да, Вы правильно поняли. Значение «true» нужно применять только для метода получения токена методами API а при подписании закодированного в Base64 тела запроса документа Акта ПП применяется значение «false».

Удовлетворены ли Вы решением проблемы? Ожидаем ответа на почту mark@ismet.kz в течении 3х дней, затем заявка автоматически будет закрыта.
6. vera_bo 08.02.23 16:26 Сейчас в теме
(4)
При анализе файла «Скрипт в поле HTML документа 1С для получения ЭЦП в CMS» обнаружено что в поле «args: ["PKCS12", "SIGNATURE", xmlData, true]» у Вас указано значение «true». Прошу поменять значение «true» на «false» и повторно отправить запрос.

А вы подписываете данные не с помощью библиотеки KalkanCryptCOMLib? Какие есть еще возможности для подписания в 1с?
Спасибо за код, увидела, где была ошибка в запросе - надо было в теле запроса в конце добавить "Символы.ВК + Символы.ПС". Запрос теперь принимается, но теперь ошибка 409, "Запрос не может быть выполнен из-за конфликтного обращения к ресурсу". Я так понимаю, это из-за неправильной подписи.
7. azamatagent 09.02.23 11:40 Сейчас в теме
(6)Нет, использовалось свойство "OnClick()" поля HTML-документа, размещенного на управляемой форме. Эта служебная форма открывается при вызове команды "Отправить/Обновить/Отозвать" Акт приема-передачи. Само событие содержит вызов скрипта JS для НУЦ РК для получения хеша ключа ЭЦП и подписи. Сам скрипт, к сожалению, предоставить не могу, в планах разместить на infostart.ru в виде обработки/расширения для интеграции с различными ИС Республики Казахстан применяющих ЭЦП.
5. azamatagent 08.02.23 06:43 Сейчас в теме
Функция исмпт_АктПриемаПередачиВыданный_ОтправитьАкт(СтруктураОтветаСервера, СтруктураПодписи, ТокенАвторизации, ПараметрыСервера, ДокументСсылка) 
	
	Если ЗначениеЗаполнено(ДокументСсылка.ИдентификаторАкта) = Истина Тогда
				
		СтруктураОтветаСервера = исмпт_АктПриемаПередачиВыданный_ОбновитьАкт(СтруктураОтветаСервера, ТокенАвторизации, ПараметрыСервера, ДокументСсылка);
		
	Иначе	
	
		// api/v3/true-api/edo-api/outgoing-documents/formal  
		
		content = СтруктураПодписи["content"];	 
			
		signature = СтруктураПодписи["field_data_for_signature"]; 
		signature = СтрЗаменить(СтрЗаменить(signature, Символы.ВК, ""), Символы.ПС, "");
				
		ПараметрыЗапроса = Новый Структура;
		ПараметрыЗапроса.Вставить("content", content);
		ПараметрыЗапроса.Вставить("signature", signature); 
		
		Разделитель = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
		ТелоЗапроса = "";
		Для каждого Параметр Из ПараметрыЗапроса Цикл
			ДобавитьПараметрВТелоЗапроса(ТелоЗапроса, Параметр.Ключ, Параметр.Значение, Разделитель);
		КонецЦикла;
		ТелоЗапроса = Лев(ТелоЗапроса, СтрДлина(ТелоЗапроса) - 2) + "--" + Символы.ВК + Символы.ПС;

		АдресРесурса = "/api/v3/true-api/edo-api/outgoing-documents/formal";
	                   
		Заголовки = Новый Соответствие;
		Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);	     
		
		РезультатЗапроса = ВыполнитьЗапросКСерверу(АдресРесурса, Заголовки, ТелоЗапроса, "POST", ТокенАвторизации);     
		
		Если (РезультатЗапроса["КодСостояния"] = 200) Или (РезультатЗапроса["КодСостояния"] = 201) Или (РезультатЗапроса["КодСостояния"] = 202) Тогда
			
			ЧтениеJSON = Новый ЧтениеJSON;
			ЧтениеJSON.УстановитьСтроку(РезультатЗапроса["ТекстОтвета"]);  
			
			РезультатЗапроса = ПрочитатьJSON(ЧтениеJSON);

			ИдентификаторАкта = РезультатЗапроса["id"];
			
		Иначе
			
			СтруктураОтветаСервера["ТекстОшибки"] = РезультатЗапроса["ТекстОтвета"];
			
			Возврат СтруктураОтветаСервера;
			
		КонецЕсли;  
		
		ПаузаВСекундах(10);
				
		Если ЗначениеЗаполнено(СтруктураОтветаСервера["ТекстОшибки"]) = Истина Тогда	
			Возврат СтруктураОтветаСервера;							
		КонецЕсли;
		
		ДокументОбъект = ДокументСсылка.ПолучитьОбъект();
		ДокументОбъект.ИдентификаторАкта = ИдентификаторАкта; 			
		Попытка 					
			ДокументОбъект.Записать(РежимЗаписиДокумента.Запись); 					
		Исключение										
			СтруктураОтветаСервера["ТекстОшибки"] = ОписаниеОшибки();					
		КонецПопытки;
		
		Если ЗначениеЗаполнено(СтруктураОтветаСервера["ТекстОшибки"]) = Истина Тогда 					
			Возврат СтруктураОтветаСервера;							
		КонецЕсли;
		
		СтруктураОтветаСервера = исмпт_АктПриемаПередачиВыданный_ОбновитьАкт(СтруктураОтветаСервера, ТокенАвторизации, ПараметрыСервера, ДокументСсылка);
			 		
	КонецЕсли;	
			
	Возврат СтруктураОтветаСервера;

КонецФункции
Показать
Прикрепленные файлы:
Инструкция по работе с API для пользователей ИС МПТ_V3.docx
Оставьте свое сообщение
Вакансии
1С аналитик
Москва
зарплата от 210 000 руб.
Полный день

Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)