我正在尝试使用SOAP :: Lite模块进行简单的API调用(至少这是我刚开始时的想法)。我正在使用一种公共可用的SOAP API here来添加两个数字。我收到以下错误消息:
服务器无法识别HTTP标头SOAPAction的值: http://tempuri.org/#Add。
我在SOAP :: Lite中启用了调试,看来我的请求格式不正确。我怀疑intA和intB中指定的类型(xsi:type =“ xsd:int”)引起了问题。
来自调试的请求:
<?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";
注意:我尝试在SOAPUI工具中加载WSDL,并且该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,看看是否有帮助。
欢呼
答案 0 :(得分:0)
URI和方法名(Add
)连接在一起以构建http标头
名为SOAPAction。
URI必须以“ /”结尾。 SOAP :: Lite将它们与“#”合并。
很久以前,我遇到了同样的问题。发现基于.NET的Web服务令人失望,无法看到“#”并通过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...