Вызов простого API-интерфейса Soap с использованием Perl's Soap :: Lite - PullRequest
0 голосов
/ 09 октября 2018

Я пытаюсь сделать простой вызов API (по крайней мере, так я думал изначально, когда начинал), используя модуль SOAP :: Lite.Я использую один из общедоступных SOAP API здесь , чтобы добавить два числа.Я получаю следующую ошибку:

Сервер не распознал значение HTTP-заголовка SOAPAction: http://tempuri.org/#Add.

Я включил отладку в SOAP :: Lite и, похоже,мой запрос сформирован неправильно.Я подозреваю, что указанный тип (xsi: type = "xsd: int") в intA и intB вызывает проблему.

Запрос отладки:

<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soap="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:Body>
    <Add xmlns="http://tempuri.org/">
      <intA xsi:type="xsd:int">5</intA>
      <intB xsi:type="xsd:int">10</intB>
    </Add>   
 </soap:Body> </soap:Envelope>

Вот мой код Perl:

#!/usr/bin/env perl

use strict;
use warnings;
use SOAP::Lite;
#use SOAP::Lite +trace => 'all';    

    SOAP::Lite->import(trace => 'debug');

    #my $uri = 'http://tempuri.org/';
    my $proxy = 'http://www.dneonline.com/calculator.asmx';
    my $ns = 'http://tempuri.org/'; 

    my $client = SOAP::Lite
            ->readable(1)
            ->uri($ns)
            ->proxy($proxy);

    my $param1 = SOAP::Data->name("intA" => $x);
    my $param2 = SOAP::Data->name("intB" => $y);

    my $response = $client->Add($param1,$param2);

    print "Result is $response \n";

Примечание: я попытался загрузить WSDL в инструмент SOAPUI, и там API работает нормально,

ОБНОВЛЕНИЕ

Как и предположил @simbabque, я попытался отладить, используя LWP :: ConsoleLogger

Заголовок выглядит так:

.---------------------------------+-----------------------------------------.
| Request (before sending) Header | Value                                   |
+---------------------------------+-----------------------------------------+
| Accept                          | text/xml, multipart/*, application/soap |
| Content-Length                  | 549                                     |
| Content-Type                    | text/xml; charset=utf-8                 |
| SOAPAction                      | "http://tempuri.org/#Add"               |
| User-Agent                      | SOAP::Lite/Perl/1.27                    |
'---------------------------------+-----------------------------------------'

Понятия не имею, откуда взялся #.Может быть, я попробую SOAP :: Simple и посмотрю, поможет ли это.

Cheers

1 Ответ

0 голосов
/ 10 октября 2018

URI и имя метода (Add) объединяются для создания заголовка http с именем SOAPAction.

URI должен заканчиваться на "/".SOAP :: Lite объединяет их с "#".

Давным-давно у меня возникла такая же проблема.Обнаружил, что веб-сервисы на основе .NET разочарованы тем, что увидели «#» и прочитали об этом решении - со справочных страниц - с помощью обработчика on_action, который просто объединяет URI и имя метода.Все это хорошо документировано в man SOAP :: Lite

my $client = SOAP::Lite->new(
  readable => 1,
  # uri is the same as package/class name into cgi file; must end with "/"
  uri => $ns, 
  # on action corrects SOAPAction to make .NET happy. .NET dislike the '#' 
  # $_[1] will contain method name on $client->call('someMethName')
  on_action => sub { return '"'. $ns . $_[1] .'"'; },  
  # proxy is the full resource URL of aspx/php/cgi/pl wich implements method name 
  proxy => $proxy);
# rest of your code...
...