2

我刚刚使用 SOAP::Lite 在 Perl 中创建了一个 Web 服务客户端。

我设法很容易地调用了我的网络服务的一个方法,但是由于一些未知的原因,它有时可以工作,有时它不会工作。

这是我的 perl 客户端代码:

my $client = SOAP::Lite->uri("http://loa.webservice")
                        ->service("http://localhost:8888/LogAnalyzerWS/services/DataReceiver?wsdl");
my $res;
do {
    sleep(2);
    print ("ok \n");
    $res = $client->sendData($data);
}while(!defined $res);

print $res, "\n";

如果结果未定义,我尝试添加一个 while 循环来重新发送数据,但它不起作用。

在对 SOAP::Lite 跟踪日志文件进行一些分析后,我发现在请求期间,有一个参数发生了变化。

这是正确的 xml 肥皂请求:

<?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"     xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soap:Body>
            <ns:sendData>
                <element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
            </ns:sendData>
        </soap:Body>
    </soap:Envelope>

正确答案:

<?xml version='1.0' encoding='utf-8'?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
            <ns:sendDataResponse xmlns:ns="http://webservice.loa">
                <ns:return>1</ns:return>
        </ns:sendDataResponse>
    </soapenv:Body>
</soapenv:Envelope>

这是错误的 xml 请求:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ax21="http://metier.loa/xsd" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:ns="http://webservice.loa" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Body>
        <ns:sendData>
            <element xsi:type="xs:base64Binary">PD94bWwgdmVyc2lvbj0</element>
        </ns:sendData>
    </soap:Body>
</soap:Envelope>

有了答案:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:Action>http://www.w3.org/2005/08/addressing/soap/fault</wsa:Action>
    </soapenv:Header>
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:VersionMismatch</faultcode>
            <faultstring>Only SOAP 1.1 or SOAP 1.2 messages are supported in the system</faultstring>
            <detail />
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>

如您所见, xmlns:soap 在正确请求和错误请求中没有相同的值:对于正确请求,它是:

"http://schemas.xmlsoap.org/soap/envelope/"

对于有缺陷的,它是:

"http://schemas.xmlsoap.org/wsdl/soap/"

任何想法为什么 SOAP::Lite 会自行更改此参数?

4

2 回答 2

2

问题来自 SOAP::Lite 中处理名称空间的方式。请参阅RT cpan 上的此问题。Axis 2 正在生成一个 wsdl,然后由 SOAP::Lite 解析,并且 SOAP::Lite::Serializer 设置的哈希中的 xmlns:soap 的值被 wsdl 的解析错误地修改了。

要解决这个问题,请在代码的最开始使用它(在 SOAP::Lite 中设置 wsdl 之前):

$SOAP::Constants::PREFIX_ENV = 'SOAP-ENV';
于 2014-06-06T14:09:32.850 回答
0

也可以使用方法envprefix:

$client->envprefix('SOAP-ENV');

这段代码对我有用:

use SOAP::Lite +trace => [ qw(debug) ]; # to get all logging without transport messages

my $service = SOAP::Lite->service('https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL');
$service->soapversion('1.1');    
$service->readable(1);
$service->envprefix('SOAP-ENV');
$service->bodyattr({ xmlns => 'http://web.cbr.ru/' });

my $result = $service->GetCursOnDate('2021-02-05T00:00:00');
于 2021-02-05T00:28:55.980 回答