1

我的公司使用了很多内部 API,这些 API 使用非常具体的标题和格式要求。我是 SOAP::Lite 的新手,我正试图让它在公司的框架内工作。

尝试#1: 理想情况下,我希望能够只获取原始 XML 模板(见文章底部),填充一些占位符变量,然后使用以下代码将其发送到端点:

my $client = SOAP::Lite->new( proxy => "$serviceURL");
my $reply = $client->InquireEnterpriseOrderDataRequest($rawxml);

但是,这会导致我的标头和请求部分被包含在它自己的“信封”、“正文”和“InquireEnterpriseOrderDataRequest”中,被服务拒绝。

尝试#2: 接下来我尝试将我的请求分成两部分:标头和请求并使用SOAP::DataSOAP::Header发送它们:

my $rawxmlheader = '<ns2:MessageHeader xmlns:ns2="http://mycompany.com/MessageHeader.xsd" xmlns="http://mycompany.com/CingularDataModel.xsd">
 <ns2:TrackingMessageHeader>
    <version>111</version>
    <originalVersion/>
    <messageId/>
    <originatorId>ABC</originatorId>
    <responseTo/>
    <returnURL/>
    <timeToLive>360000</timeToLive>
    <conversationId>9AF0E9281A524262980F5284F4C57888_CCE423E277C74FA9A84D2155CD612EB3_0</conversationId>
    <routingRegionOverride/>
    <dateTimeStamp>2017-05-12T12:47:53Z</dateTimeStamp>
    <uniqueTransactionId>mytransid</uniqueTransactionId>
 </ns2:TrackingMessageHeader>
 <ns2:SecurityMessageHeader>
    <userName>myusername</userName>
    <userPassword>mypass</userPassword>
 </ns2:SecurityMessageHeader>
 <ns2:SequenceMessageHeader>
    <sequenceNumber/>
    <totalInSequence/>
 </ns2:SequenceMessageHeader>
</ns2:MessageHeader>';

my $rawxmlrequest = '<OrderSearchCriteria>
    <OrderDetails>
       <SearchByOrderAction>
      <orderActionNumber>12345654</orderActionNumber>
      <orderActionVersion>1</orderActionVersion>
       </SearchByOrderAction>
    </OrderDetails>
 </OrderSearchCriteria>
 <provisioningDetailsIndicator>true</provisioningDetailsIndicator>';

    my $client = SOAP::Lite->new( proxy => "$serviceURL");
    my $header = SOAP::Header->type('xml' => $rawxmlheader);
    my $elem = SOAP::Data->type('xml' => $rawxmlrequest);
    my @arguments;
    push(@arguments, $header);
    push(@arguments, $elem);
    my $reply = $client->InquireEnterpriseOrderDataRequest(@arguments);

除了 InquireEnterpriseOrderDataRequest blob 不包含似乎需要的 xsi:schemaLocation、xmlns 或 xmlns:xsi 值之外,这产生了与所需内容非常相似的请求。

尝试#3: 现在我正抓紧救命稻草,所以我还尝试使用以下内容精细地创建我自己的 XML:

my $temp_elements = 
        SOAP::Data->name("OrderSearchCriteria" => \SOAP::Data->value(
        SOAP::Data->name("OrderDetails" => \SOAP::Data->value(
        SOAP::Data->name("SearchByOrderAction" => \SOAP::Data->value(
        SOAP::Data->name("orderActionNumber" => '301496944'),
        SOAP::Data->name("orderActionVersion" => '3')
        )
        )
    )
    ))
        )->type("SomeObject");

my $client = SOAP::Lite->new( proxy => "$serviceURL");
my $reply = $client->InquireEnterpriseOrderDataRequest($temp_elements);

这里的问题是我不知道如何包含 xsi:schemaLocation、xmlns 和 xmlns:xsi 值或添加标题信息。

当然,我想采用最简单的实现方式,但欢迎提出任何建议!提前致谢!

要求的请求格式:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header>
      <ns2:MessageHeader xmlns:ns2="http://mycompany.com/MessageHeader.xsd" xmlns="http://mycompany.com/CingularDataModel.xsd">
         <ns2:TrackingMessageHeader>
            <version>111</version>
            <originalVersion/>
            <messageId/>
            <originatorId>ABC</originatorId>
            <responseTo/>
            <returnURL/>
            <timeToLive>360000</timeToLive>
            <conversationId>9AF0E9281A524262980F5284F4C57888_CCE423E277C74FA9A84D2155CD612EB3_0</conversationId>
            <routingRegionOverride/>
            <dateTimeStamp>2017-04-11T18:47:53Z</dateTimeStamp>
            <uniqueTransactionId>mytransid</uniqueTransactionId>
         </ns2:TrackingMessageHeader>
         <ns2:SecurityMessageHeader>
            <userName>myusername</userName>
            <userPassword>mypass</userPassword>
         </ns2:SecurityMessageHeader>
         <ns2:SequenceMessageHeader>
            <sequenceNumber/>
            <totalInSequence/>
         </ns2:SequenceMessageHeader>
      </ns2:MessageHeader>
   </SOAP-ENV:Header>
  <SOAP-ENV:Body>
      <InquireEnterpriseOrderDataRequest xsi:schemaLocation="http://mycompany.com/InquireEnterpriseOrderDataRequest.xsd" xmlns="http://mycompany.com/InquireEnterpriseOrderDataRequest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <OrderSearchCriteria>
            <OrderDetails>
               <SearchByOrderAction>
                  <orderActionNumber>12345654</orderActionNumber>
                  <orderActionVersion>1</orderActionVersion>
               </SearchByOrderAction>
            </OrderDetails>
         </OrderSearchCriteria>
         <provisioningDetailsIndicator>true</provisioningDetailsIndicator>
      </InquireEnterpriseOrderDataRequest>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
4

1 回答 1

1

这应该使用 SOAP::Lite 请求生成所需的响应。

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

$on_action = '';
$proxy = 'http://serviceURL';

$soap = SOAP::Lite->new(proxy => $proxy);
$soap->on_action(sub {$on_action});
$soap->readable(1);
$soap->autotype(0);
$soap->serializer->register_ns('http://mycompany.com/InquireEnterpriseOrderDataRequest.xsd' => 'xsi');
$soap->serializer->register_ns('http://mycompany.com/InquireEnterpriseOrderDataRequest.xsd' => 'xsi:schemaLocation');
$soap->default_ns('http://mycompany.com/InquireEnterpriseOrderDataRequest.xsd');
$soap->envprefix('SOAP-ENV');

$sheader = SOAP::Header->name(MessageHeader =>\SOAP::Header->value(SOAP::Header->name(TrackingMessageHeader => \SOAP::Header->value(
               SOAP::Header->name(version => 111),
               SOAP::Header->name(originalVersion => ''),
               SOAP::Header->name(messageId => ''),
               SOAP::Header->name(originatorId => 'ABC'),
               SOAP::Header->name(responseTo => ''),
               SOAP::Header->name(returnURL => ''),
               SOAP::Header->name(timetoLive => 360000),
               SOAP::Header->name(conversationId => '9AF0E9281A524262980F5284F4C57888_CCE423E277C74FA9A84D2155CD612EB3_0'),
               SOAP::Header->name(routingRegionOverride => ''),
               SOAP::Header->name(dateTimeStamp => '2017-04-11T18:47:53Z'),
               SOAP::Header->name(timetoLive => 'mytransid'),
            ))->prefix('ns2')))->attr({'xmlns:ns2' => 'http://mycompany.com/MessageHeader.xsd',xmlns => 'http://mycompany.com/CingularDataModel.xsd'})->prefix('ns2');

push @request,(
        SOAP::Data->name(OrderSearchCriteria => \SOAP::Data->value(
           SOAP::Data->name(OrderDetails => \SOAP::Data->value(
              SOAP::Data->name(SearchByOrderAction => \SOAP::Data->value(
                 SOAP::Data->name(orderActionNumber => 12345654),
                 SOAP::Data->name(orderActionVersion => 1),
)))))));
$reply = $soap->InquireEnterpriseOrderDataRequest($sheader,@request);
于 2017-05-22T14:22:13.603 回答