使用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,我预计会收到错误&#34;无法识别的方法&#39; MT_PList_Request&#39;。可用方法列表:SI_PList_2_SRM_SO&#34;
此外,我无法使用发送原始XML的方法
my $element = SOAP::Data->type('xml' => $xml);
my $result = $soap->SI_PList_2_SRM_SO($element);
因为使用参数调用的SI_PList_2_SRM_SO会获得异常&#34;类型&#39; DT_PList_Request&#39;的模式/命名空间未指定&#34;。
如果我将service
方法更改为new
方法,则预计不会更改任何内容,无论如何请求xml都有错误的标记。