首页 > 解决方案 > 使用 SOAP::Lite 形成 SOAP 请求 xml

问题描述

我在使用 SOAP::Lite perl-module 形成 SOAP 请求时遇到了一些麻烦。

这是 WSDL 模式:

<wsdl:definitions xmlns:p1="http://example.com/SOAP/PList" name="SI_PList_2_SRM_SO" targetNamespace="http://example.com/SOAP/PList">
    <wsdl:documentation />
    <wsp:UsingPolicy wsdl:required="true" />
    <wsp:Policy wsu:Id="OP_SI_PList_2_SRM_SO" />
    <wsdl:types>
        <xsd:schema xmlns="http://example.com/SOAP/PList" targetNamespace="http://example.com/SOAP/PList">
            <xsd:element name="MT_PList_Response" type="DT_PList_Response" />
            <xsd:element name="MT_PList_Request" type="DT_PList_Request" />
            <xsd:simpleType name="DT_PList_Request">
            </xsd:simpleType>
            <xsd:complexType name="DT_PList_Response">
            </xsd:complexType>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="MT_PList_Request">
        <wsdl:documentation />
        <wsdl:part name="MT_PList_Request" element="p1:MT_PList_Request" />
    </wsdl:message>
    <wsdl:message name="MT_PList_Response">
        <wsdl:documentation />
        <wsdl:part name="MT_PList_Response" element="p1:MT_PList_Response" />
    </wsdl:message>
    <wsdl:portType name="SI_PList_2_SRM_SO">
        <wsdl:operation name="SI_PList_2_SRM_SO">
            <wsdl:documentation />
            <wsp:Policy>
                <wsp:PolicyReference URI="#OP_SI_PList_2_SRM_SO" />
            </wsp:Policy>
            <wsdl:input message="p1:MT_PList_Request" />
            <wsdl:output message="p1:MT_PList_Response" />
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="SI_PList_2_SRM_SOBinding" type="p1:SI_PList_2_SRM_SO">
        <wsdl:operation name="SI_PList_2_SRM_SO"/>
    </wsdl:binding>
    <wsdl:service name="SI_PList_2_SRM_SOService">
        <wsdl:port name="HTTPS_Port" binding="p1:SI_PList_2_SRM_SOBinding">
            <soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" location="https://s.example.com/api/etender/SI_PList_2_SRM_SO" />
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

使用 SOAP API 的说明告诉我应该调用过程 SI_PList_2_SRM_SO。我写了简单的测试脚本:

use SOAP::Lite +trace => [ transport => sub { say $_[0]->as_string } ];

my $api_host = "http://s.example.com/srm/api/etender/wsdl";
my $api_namespace = "http://example.com/SOAP/PList";

#my $soap = SOAP::Lite->new(uri => $api_namespace, proxy => $api_host);
my $soap = SOAP::Lite->service($api_host);
$soap->serializer->envprefix('soapenv');
my $result = $soap->SI_PList_2_SRM_SO();

它形成请求:

<soapenv:Envelope xmlns:p1="http://example.com/SOAP/PList" >
   <soapenv:Body>
      <p1:SI_PList_2_SRM_SO xsi:nil="true" />
   </soapenv:Body>
</soapenv:Envelope>

但是从对服务的 SOAP 服务器端的支持我知道正确的请求 xml 必须是:

<soapenv:Envelope xmlns:get="http://example.com/SOAP/PList">
   <soapenv:Header/>
   <soapenv:Body>
      <get:MT_PList_Request>test</get:MT_PList_Request>
   </soapenv:Body>
</soapenv:Envelope>

所以我应该在 Body 中有另一个标签。我还检查了SOAP Client Test Service,它用 MT_PList_Request 标签形成了正确的请求 XML。

如果我直接使用 MT_PList_Request,我预计会收到错误“无法识别的方法 'MT_PList_Request'。可用方法列表:SI_PList_2_SRM_SO”

我也不能使用像这样发送原始 XML 的方法

my $element = SOAP::Data->type('xml' => $xml);
my $result = $soap->SI_PList_2_SRM_SO($element);

因为使用参数调用的 SI_PList_2_SRM_SO 得到异常“未指定类型 'DT_PList_Request' 的架构/命名空间”。

如果我将service方法更改为new方法,预计什么都不会改变,无论如何请求 xml 有错误的标签。

标签: xmlperlsoap

解决方案


推荐阅读