Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Интернет » Web-программирование » Soap и Perl

Модерирует : Cheery

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Здравствуйте, друзья.
Никак не могу понять как правильно составить запросы soap в perl и получить ответы. Яндекс и Гугл не дают чёткого ответа.
В общем задача: есть сайт поставщика и у него API по остаткам работает через soap. Нужно отправить запрос с параметром и получить ответ по наличию.
Дали вот такую ссылку http://37.128.92.210:885/WebService.asmx
и pdf инструкцию, в которой написано следующее:
 

Цитата:
2. Access to WebSerwice
URL access to the Web Service: http://37.128.92.210:885/WebService.asmx
User name: will be provided by Helikon-Tex®
Password: will be provided by Helikon-Tex
 
3. The procedures
3.1. GetAllProducts(string cus, bool only_in_stock, Lang lang, Currency currency)
The procedure returns a list of all products available in the system B2B of Helikon-Tex®.
The default procedure returns the products both available and unavailable.
Parameters:

  • cus – customer ID (company name which is used to login to B2B panel),
  • only_in_stock – returns only the available products,
  • lang – language of products descriptions,
  • currency – prices currency.

3.2. GetProductById(string cus, int id, Lang lang, Currency currency)
The procedure returns a single product by product id.
Parametry:

  • cus – customer ID (company name which is used to login to B2B panel),
  • id – product ID,
  • lang – language of products descriptions,
  • currency – prices currency.

3.3. GetProductByCode(string cus, string code, Lang lang, Currency currency)
Procedura zwraca pojedynczy produkt według przekazanego kodu produktu.
Parametry:

  • cus – customer ID (company name which is used to login to B2B panel),
  • code – product code,
  • lang – language of products descriptions,
  • currency – prices currency.4. Definiton of product class
    product
  • int product_id – unique product id,
  • string product_code – unique product code,
  • string product_name – product name,
  • decimal product_price – purchace price,
  • decimal product_price_min – MRP,
  • decimal product_price_suggested – SRP,
  • string product_producer – product manufacturer,
  • string product_brand – product brand,
  • decimal product_weight – product weight,
  • string product_ean – EAN code,
  • string product_cn – CN code,
  • string product_unit – unit of measure,
  • string product_specification – material specification,
  • string product_description – product Description,
  • List variants – list of variants (features) of the product
    o int variant_id – unique id variant (features) of the product
    o string variant_type – type of variant (features)
    o string variant_name – name of the variant (features)
    o decimal variant_stock – number of available products in stock in variant
    (features)

Wartosc zwracana w zmiennej variant_stock:

  • varinat_stock >= 0 – the exact state of stock in pieces,
  • variant_stock =-1 – corresponds to the sign yellow availability in IZAM (small amount)
  • variant_stock = -2 – corresponds to the sign green availability in IZAM (high amount)

5. Auxiliary variables
enum Lang { Polish, English }
enum Currency { PLN, USD, EUR, GBP }
 
 
 

 
Помогите составить запрос на PERL и получить ответ.
Заранее благодарю.

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 11:37 14-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger
прочитать для общего понимания
https://ru.wikipedia.org/wiki/SOAP
 
чтобы меньше писать удобнее использовать модуль https://metacpan.org/pod/SOAP::Lite
простые примеры использования - https://www.perl.com/pub/2001/01/soap.html/#client
в самом модуле полно примеров в t/*.t и examples/*.pl

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 23:08 14-05-2020
LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Просмотрел кучу информации что нашёл по запросам "soap perl example", но так до конца и не понял как же мне всё-таки отправить данные и получить ответ.
Все куски кода, что нашлись не дали мне чёткого понимания структуры запросов и ответов.  
С помощью программы SoapUI я всё-таки смог сделать запрос и получить ответ. Но вот как это реализовать с помощью Soap::Lite я так и не понял.
Адрес WSDL сервера я знаю.

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 16:24 27-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger

Цитата:
Но вот как это реализовать с помощью Soap::Lite я так и не понял

ну вот же конкретный пример
https://metacpan.org/pod/SOAP::Lite#Example-implementations
либо RPC, либо ниже WSDL
вот еще куча примеров - https://metacpan.org/source/PHRED/SOAP-Lite-1.27/examples/WSDL
простейший

Код:
my $service = SOAP::Lite
  ->service('ссылка на WSDL');
 
print $service->процедура(аргументы), "\n";

авторизация - обычно пишется в URL, через http(s)://имя_пользователя:пароль@URL
может так - зависит от ситуации

Код:
sub SOAP::Transport::HTTP::Client::get_basic_credentials {  
  return username => 'password';
}

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 04:14 28-05-2020 | Исправлено: Mavrikii, 04:21 28-05-2020
LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Пишу так:
 

Код:
 
my $soap = SOAP::Lite->new( proxy => 'http://37.128.92.210:885/WebService.asmx' );
$soap->service( "http://37.128.92.210:885/WebService.asmx?WSDL" );
$soap->uri("http://37.128.92.210:885/WebService.asmx");
$soap->headerattr({ userName => 'user',
                    password => 'pass' });
$soap->bodyattr({     cus => 'CUS',
                    code => 'TR-VGCT-NCR-MCM',
                    lang => 'English',
                    currency => 'EUR' });
 
print $soap->result;
 
 

В ответ получаю "1".  
Что не так я делаю?

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 18:01 29-05-2020 | Исправлено: LonelyRanger, 18:03 29-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger
А принципиально, чтобы именно на perl? Так-то curl и wget умеют отправлять SOAP запросы.
 
Надо вызывать конкретную функцию, а не WSDL, как мне кажется?  
Попробуй сначала в онлайн клиенте потестить  
https://wsdlbrowser.com/soapclient?wsdl_url=http%3A%2F%2F37.128.92.210%3A885%2FWebService.asmx%3FWSDL&function_name=GetProductByCode
 
Добавлено:
Как вариант, можно попробовать запихнуть XML в запрос:
 
use SOAP::Lite;
my $xml = <<'XML';
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
  <SOAP-ENV:Body>
    <ns1:GetProductByCode>
      <ns1:cus>CUS</ns1:cus>
      <ns1:code>TR-VGCT-NCR-MCM</ns1:code>
      <ns1:lang>English</ns1:lang>
      <ns1:currency>EUR</ns1:currency>
    </ns1:GetProductByCode>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML
 
my $soap = SOAP::Lite->service('http://37.128.92.210:885/WebService.asmx?WSDL');
my $res = $soap->GetProductByCode(SOAP::Data->type( 'xml' => $xml ));

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 18:06 29-05-2020 | Исправлено: Fenrizz, 18:20 29-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger

Цитата:
Что не так я делаю?

так пробовали?

Код:
 
my $service = SOAP::Lite
  ->service('http://37.128.92.210:885/WebService.asmx?WSDL');
 
print $service->GetProductByCode('CUS', 'TR-VGCT-NCR-MCM', 'English', 'EUR' ), "\n";

добавить только авторизацию
 

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 20:37 29-05-2020
LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
 так пробовали?  

Вот так написал:

Код:
 
my $service = SOAP::Lite
  ->service('http://37.128.92.210:885/WebService.asmx?WSDL')
  ->uri("http://37.128.92.210:885/WebService.asmx")
  ->headerattr({ userName => 'user', password => 'pass' });
print $service->GetProductByCode(cus => 'CUS', code => 'TR-VGCT-NCR-MCM', lang => 'English', currency => 'EUR' ), "\n";  
 

 
В итоге ничего не выводит на экран.
 
В этом варианте тоже пусто

Код:
 
my $service = SOAP::Lite
  ->service('http://37.128.92.210:885/WebService.asmx?WSDL')
  ->uri("http://37.128.92.210:885/WebService.asmx")
  ->headerattr({ userName => 'user', password => 'pass' });
print $service->GetProductByCode('CUS', 'TR-VGCT-NCR-MCM', 'English', 'EUR' ), "\n";  
 

 
 
Добавлено:

Цитата:
Добавлено:
Как вариант, можно попробовать запихнуть XML в запрос:
 
use SOAP::Lite;
my $xml = <<'XML';
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
  <SOAP-ENV:Body>
    <ns1:GetProductByCode>
      <ns1:cus>CUS</ns1:cus>
      <ns1:code>TR-VGCT-NCR-MCM</ns1:code>
      <ns1:lang>English</ns1:lang>
      <ns1:currency>EUR</ns1:currency>
    </ns1:GetProductByCode>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML
 
my $soap = SOAP::Lite->service('http://37.128.92.210:885/WebService.asmx?WSDL');
my $res = $soap->GetProductByCode(SOAP::Data->type( 'xml' => $xml ));  

Написал так:

Код:
my $xml = <<'XML';
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
  <SOAP-ENV:Body>
    <ns1:GetProductByCode>
      <ns1:cus>CUS</ns1:cus>
      <ns1:code>TR-VGCT-NCR-MCM</ns1:code>
      <ns1:lang>English</ns1:lang>
      <ns1:currency>EUR</ns1:currency>
    </ns1:GetProductByCode>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML
 
my $soap = SOAP::Lite->service('http://37.128.92.210:885/WebService.asmx?WSDL');
$soap->headerattr({ userName => 'user',
                    password => 'pass' });
 
my $res = $soap->GetProductByCode(SOAP::Data->type( 'xml' => $xml ));  
print "$res\n";
 
 

На экран выдало следующее:

Код:
String value expected instead of SOAP::Data reference

 
Добавлено:

Цитата:
А принципиально, чтобы именно на perl?

В общем-то perl я боле-менее знаю.  
Мне нужно получить данные у поставщика, с ними потом произвести некоторые манипуляции и выложить на форум информацию.
Вот с получением данных у меня пока загвоздка (остальное не проблема). Если можно как-то получить эти данные и передать их perl скрипту, то я не буду возражать против такой схемы. Главное чтобы сработало.

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 22:35 29-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
curl --output GetProductByCode.xml --header "Content-Type: application/soap+xml;charset=UTF-8" --header "SOAPAction: \"http://37.128.92.210:885/WebService.asmx?op=GetProductByCode\"" -d@soap.xml "http://37.128.92.210:885/WebService.asmx?op=GetProductByCode"
 
Файл soap.xml можно взять по ссылке http://37.128.92.210:885/WebService.asmx?op=GetProductByCode
 

Цитата:
POST /WebService.asmx HTTP/1.1
Host: 37.128.92.210
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
 
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Header>
    <UserCredentials xmlns="http://tempuri.org/">
      <userName>string</userName>
      <password>string</password>
    </UserCredentials>
  </soap12:Header>
  <soap12:Body>
    <GetProductByCode xmlns="http://tempuri.org/">
      <cus>string</cus>
      <code>string</code>
      <lang>Polish or English</lang>
      <currency>PLN or USD or EUR</currency>
    </GetProductByCode>
  </soap12:Body>
</soap12:Envelope>  

 

Цитата:
Мне нужно получить данные у поставщика, с ними потом произвести некоторые манипуляции и выложить на форум информацию.  

SOAP возвращает XML и его можно его преобразовывать с помощью XSLT, так что, возможно, perl вообще не нужен.

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 23:20 29-05-2020 | Исправлено: Fenrizz, 23:34 29-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger

Код:
use SOAP::Lite +trace => [ transport => sub { print $_[0]->as_string } ];
   
$SOAP::Constants::PREFIX_ENV = 'SOAP-ENV';
 
my $service = SOAP::Lite
  ->service('http://37.128.92.210:885/WebService.asmx?WSDL');
 
print $service->GetProductByCode('CUS', 'TR-VGCT-NCR-MCM', 'English', 'EUR' ), "\n";

+trace и остальное можете убрать - это для дебага запроса и ответа.
запрос, по крайней мере, проходит, хоть и возвращается пустой ответ. может нужна авторизация, может ничего не находит - смотрите сами в каком виде отправляется и получается.

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 06:38 30-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mavrikii
Должен возвращать непустой ответ - на онлайн тестере и без логина/пароля работает.
 
Result:
 
Может, надо так?  ->service('http://37.128.92.210:885/WebService.asmx?op=GetProductByCode');

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 06:45 30-05-2020 | Исправлено: Fenrizz, 06:48 30-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Fenrizz

Цитата:
Может, надо так?  

нет, особенность в enum Lang и Currency, он их отправляет почему то неправильно, надо понять почему.
выглядит как

Код:
<lang xsi:nil="true" xsi:type="tns:Lang" /><currency xsi:nil="true" xsi:type="tns:Currency" />

то есть вызов считает, что они пустые.
 
может им не нравится мой IP ) это тоже выдает не то

Код:
use SOAP::Lite +trace => [ transport => sub { print $_[0]->as_string } ];
 
$SOAP::Constants::PREFIX_ENV = 'SOAP-ENV';
 
my $soap = SOAP::Lite->new( proxy => 'http://37.128.92.210:885/WebService.asmx?WSDL');
$soap->on_action( sub { "http://tempuri.org/GetProductByCode" });
$soap->default_ns('urn:HelloWorld');
 
my $res = $soap->call('GetProductByCode', { cus => 'CUS', code => 'TR-VGCT-NCR-MCM', lang => 'English', currency => 'EUR' });

возвращает

Цитата:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soap:Body>
      <GetProductByCodeResponse xmlns="http://tempuri.org/" />
   </soap:Body>
</soap:Envelope>

 
запрос при этом выглядит как

Цитата:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <GetProductByCode xmlns="urn:HelloWorld">
         <c-gensym3>
            <currency xsi:type="xsd:string">EUR</currency>
            <lang xsi:type="xsd:string">English</lang>
            <cus xsi:type="xsd:string">CUS</cus>
            <code xsi:type="xsd:string">TR-VGCT-NCR-MCM</code>
         </c-gensym3>
      </GetProductByCode>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 06:57 30-05-2020 | Исправлено: Mavrikii, 07:22 30-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
$soap->default_ns('urn:HelloWorld');  

 
Мне кажется, тут должно быть $soap->default_ns('http://tempuri.org/');
 
http://www.herongyang.com/Web-Services/Perl-SOAP-1-2-default_ns-Set-Default-namespace-for-Body.html
 
И вот этот момент ещё - http://www.herongyang.com/Web-Services/Perl-SOAP-1-2-DEFAULT_HTTP_CONTENT_TYPE.html

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 07:29 30-05-2020 | Исправлено: Fenrizz, 07:32 30-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Fenrizz

Цитата:
Мне кажется, тут должно быть  

это роли не играет
 

Цитата:
И вот этот момент ещё  

нет

Цитата:
HTTP/1.1 415 Unsupported Media Type

 
мне кажется тут нужна авторизация, уж не знаю как вам выдал. может им не нравится откуда я выхожу, попробуйте код.

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 07:33 30-05-2020 | Исправлено: Mavrikii, 07:46 30-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
$soap->on_action( sub { "http://tempuri.org/GetProductByCode" });  

 
Ссылка http://tempuri.org/GetProductByCode или просто http://tempuri.org/ перебрасывает на https://www.bing.com/
Возможно, надо просто "GetProductByCode" или "http://37.128.92.210:885/WebService.asmx?op=GetProductByCode"

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 08:06 30-05-2020 | Исправлено: Fenrizz, 08:12 30-05-2020
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Fenrizz

Цитата:
перебрасывает на

никто и никуда не должен перебрасывать. это не ссылка, это часть заголовка запроса.

Цитата:
Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 653
Content-Type: text/xml; charset=utf-8
SOAPAction: http://tempuri.org/GetProductByCode

и она важна, так как если неправильная, то выдает ошибку.
 

Цитата:
The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is even resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request.

Всего записей: 15097 | Зарегистр. 20-09-2014 | Отправлено: 08:11 30-05-2020 | Исправлено: Mavrikii, 08:13 30-05-2020
LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
 SOAP возвращает XML и его можно его преобразовывать с помощью XSLT, так что, возможно, perl вообще не нужен.

Perl нужен для дальнейших действий с данными.

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 20:58 30-05-2020
LonelyRanger

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

Цитата:
мне кажется тут нужна авторизация

Как задать авторизацию?

Всего записей: 42 | Зарегистр. 04-03-2008 | Отправлено: 15:38 31-05-2020
Fenrizz



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LonelyRanger
Вписать логин и пароль в соответствующие поля XML запроса:
 
    <UserCredentials xmlns="http://tempuri.org/">  
       <userName>string</userName>  
       <password>string</password>  
     </UserCredentials>  
 

Цитата:
2. Access to WebSerwice  
 URL access to the Web Service: http://37.128.92.210:885/WebService.asmx  
 User name: will be provided by Helikon-Tex®  
Password: will be provided by Helikon-Tex  

Всего записей: 677 | Зарегистр. 12-09-2017 | Отправлено: 16:08 31-05-2020 | Исправлено: Fenrizz, 16:09 31-05-2020
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Интернет » Web-программирование » Soap и Perl


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru