Ошибка с кодом состояния 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
Оставьте свое сообщение

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