9

我正在一个下订单的商业网站上工作。为了跟踪该交付,我需要向用户提供一个链接,其中包含用户填写的表单中的所有参数,以创建交付并使用 UK Mail 和邮件中提供的链接跟踪其状态。

我必须使用 UK Mail Web Service API。谁能告诉我该怎么做?我是 SOAP WSDL 的新手。

据我了解,我现在这样做了如何走得更远?我的代码低于它的基本客户端,我需要:

  1. 验证登录并使用验证令牌

  2. 我需要发送参数来创建国内作业

  3. 我也需要跟踪交货状态

这是我更新的代码:

<?php 

$LoginWebRequest = new stdClass();
$LoginWebRequest->Username = 'xxx cant show here xxx';
$LoginWebRequest->Password = 'xxx cant show here xxx';

//echo "<pre>";  print_r($LoginWebRequest); "</pre>"; exit;

$Login = new stdClass();
$Login->loginWebRequest = $LoginWebRequest;

//echo "<pre>";  print_r($Login); "</pre>"; exit; 

$soapClient = new SoapClient('somewsdl?wsdl');
$LoginResponse = $soapClient->Login($Login);

//echo "<pre>";  print_r($LoginResponse); "</pre>"; exit; 

$LoginResponse = $soapClient->Login($Login);


// -- till here my code runs fine and also gives the failed output but adding the code //below gives me error cant find out whats wrong 


$AuthenticationToken = $LoginResponse->LoginResult->AuthenticationToken;



$AddDomesticConsignmentWebRequest = new stdClass();
$AddDomesticConsignmentWebRequest->Username = 'xxxxxx';
// setting the Authentication Token from the previous step
$AddDomesticConsignmentWebRequest->AuthenticationToken = $AuthenticationToken ;
// other properties are set here...

$AddDomesticConsignment = new stdClass();
$AddDomesticConsignment->request = $AddDomesticConsignmentWebRequest;


$soapClient = new SoapClient('https://svc?wsdl');
$AddDomesticConsignmentResponse = $soapClient->AddDomesticConsignment($AddDomesticConsignment);


?>

我已经解决了所有问题并得到了我的托运,也不需要跟踪我的 api

我的 xml 是这样的,或者你可以检查 pdf

     Example XML Request:
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"        xmlns:thir="http://webapp-cl.internet-delivery.com/ThirdPartyIntegrationService">
    <soap:Header/>
    <soap:Body>
    <thir:ConsignmentTrackingSearchV1>
    <thir:UserName>mail.com</thir:UserName>
    <thir:Password>123</thir:Password>
    <thir:Token></thir:Token>
    <thir:ConsignmentNumber>01161</thir:ConsignmentNumber>
    <thir:IsPartialConsignmentNumber>false</thir:IsPartialConsignmentNumber>
    <thir:CustomerReference></thir:CustomerReference>
    <thir:IsPartialCustomerReference>false</thir:IsPartialCustomerReference>
    <thir:DeliveryPostCode></thir:DeliveryPostCode>
    <thir:MailingID></thir:MailingID>
    <thir:MaxResults>100</thir:MaxResults>
    </thir:ConsignmentTrackingSearchV1>
    </soap:Body>
    </soap:Envelope>

示例 xml 响应

      <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <soap:Body>
       <ConsignmentTrackingSearchV1Response xmlns="http://webapp-cl.internet- delivery.com/ThirdPartyIntegrationService">
        <ConsignmentTrackingSearchV1Result>
        <ResultState>Successful</ResultState>
         <ConsignmentResults>
       <ConsignmentSearchResult>
    <ConsignmentNumber>001161</ConsignmentNumber>
    <CustomerRef1/>
   <CustomerRef2/>
     <SubCustomerRef1/>
     <SubCustomerRef2/>
      <DeliveryType/>
      <ConsignmentStatus>Delivered</ConsignmentStatus>
      <DateTimeDelivered>2010-02-11T12:00:00+00:00</DateTimeDelivered>
      <ItemsDelivered>2</ItemsDelivered>
      <RecipientName>robin</RecipientName>
      <DeliveryComments/>
      <ExpectedDeliveryDate>2010-02-11T00:00:00</ExpectedDeliveryDate>
       <DeliveryService>Next Day</DeliveryService>
      <TotalItems>2</TotalItems>
      <Consignmentkey>22</Consignmentkey>
        </ConsignmentSearchResult>
         </ConsignmentResults>
        </ConsignmentTrackingSearchV1Result>
        </ConsignmentTrackingSearchV1Response>
        </soap:Body>
       </soap:Envelope>
4

2 回答 2

20

介绍

显然,这里缺少文档。不幸的是,$soapClient->__getTypes()并没有说太多。它只显示 Web 服务支持的可用复杂类型,但没有显示它们之间的关系。即使您有所有可用操作的列表及其返回的输入和输出类型$soapClient->__getFunctions(),也不能保证您可以在不知道复杂类型的确切性质或没有任何类型的文档的情况下继续进行。但幸运的是,这是一个提供 WSDL 文档的基于 SOAP 的 Web 服务。WSDL 文档描述了所有支持的操作和复杂类型,以及它们之间的关系。因此,我们只需检查 WSDL 文档就可以了解如何使用该服务。

检查 WSDL 文档有两种方法:

  1. 从 WSDL 文档生成工件(客户端类)并检查工件
  2. 查看 WSDL 文档和 XML Schema 文档。

1. 神器

工件可以由 Java 或 C# 等强类型语言提供的工具生成。https://qa-api.ukmail.com/Services/UKMAuthenticationServices/页面建议使用该工具svcutil.exe为 C# 编程语言生成工件,或者您也可以使用该wsimport工具为 Java 编程语言生成工件。我怀疑是否有任何好的工具可以为 PHP 编程语言生成工件。

2. WSDL 文档和 XML Schemas

如果您不熟悉 C# 或 Java,您始终可以通过查看 WSDL 文档和 XML Schemas 来检查它。XML 模式可以包含在 WSDL 文档中或从外部文件导入。WSDL 文档描述了可以在 Web 服务上执行的操作,而 XML 模式描述了复杂的类型及其关系。

行动

我写了介绍部分,以便您知道如何自己做。下面我想展示一个例子。为了检查 WSDL 文档,我使用了两种方法。首先,我使用该wsimport工具生成了工件,然后我阅读了很多 XML。

import此服务的 WSDL 文档使用语句分为几个文件。因此,为了找到所有操作和复杂类型,您必须遵循这些import语句。

验证

如果我们查看 Authentication Service 的 WSDL 文档(location),我们可以看到它导入了另一个 WSDL 文档:

<wsdl:import namespace="http://tempuri.org/" location="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?wsdl=wsdl1"/>

后者(location)又导入另一个:

<wsdl:import namespace="http://www.UKMail.com/Services/Contracts/ServiceContracts" location="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?wsdl=wsdl0"/>

最后一个(location),导入所有相关的 XML Schema:

<wsdl:types>
  <xsd:schema targetNamespace="http://www.UKMail.com/Services/Contracts/ServiceContracts/Imports">
    <xsd:import schemaLocation="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?xsd=xsd0" namespace="http://www.UKMail.com/Services/Contracts/ServiceContracts"/>
    <xsd:import schemaLocation="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
    <xsd:import schemaLocation="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?xsd=xsd2" namespace="http://www.UKMail.com/Services/Contracts/DataContracts"/>
    <xsd:import schemaLocation="https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/UKMWebAPICommon.WebResponses"/>
  </xsd:schema>
</wsdl:types>

它还描述了也可以通过调用查看的操作$soapClient->__getFunctions()

Array
(
    [0] => LoginResponse Login(Login $parameters)
    [1] => LogoutResponse Logout(Logout $parameters)
)

在这里,我们看到该Login()操作接受$parameterstypeLogin作为其参数并返回 type 的响应LoginResponse。这是它在 WSDL 文档中的外观:

<wsdl:operation name="Login">
  <wsdl:input wsaw:Action="http://www.UKMail.com/Services/IUKMAuthenticationService/Login" message="tns:IUKMAuthenticationService_Login_InputMessage"/>
  <wsdl:output wsaw:Action="http://www.UKMail.com/Services/Contracts/ServiceContracts/IUKMAuthenticationService/LoginResponse" message="tns:IUKMAuthenticationService_Login_OutputMessage"/>
</wsdl:operation>

Login是一个复杂类型,这可以在一个导入的 XML Schema 文档(s​​chemaLocation)中看到:

<xs:element name="Login">
  <xs:complexType>
    <xs:sequence>
      <xs:element xmlns:q1="http://www.UKMail.com/Services/Contracts/DataContracts" minOccurs="0" name="loginWebRequest" nillable="true" type="q1:LoginWebRequest"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

它有一个名为的元素loginWebRequest,它也是一个复杂的类型LoginWebRequest,在另一个导入的 XML Schema 中进行了描述:

<xs:complexType name="LoginWebRequest">
  <xs:sequence>
    <xs:element name="Password" nillable="true" type="xs:string"/>
    <xs:element name="Username" nillable="true" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

LoginWebRequest更简单。它有两种简单的类型UsernamePassword类型String

在 PHP 中,复杂类型由stdClass. 因此,为了调用Login()操作,我们必须创建两个对象LoginLoginWebRequest

$LoginWebRequest = new stdClass();
$LoginWebRequest->Username = 'Username';
$LoginWebRequest->Password = 'p@$$w0rd';

$Login = new stdClass();
$Login->loginWebRequest = $LoginWebRequest;

$soapClient = new SoapClient('https://qa-api.ukmail.com/Services/UKMAuthenticationServices/UKMAuthenticationService.svc?wsdl');
$LoginResponse = $soapClient->Login($Login);

这给了我们一个类型的结果LoginResponse

<xs:element name="LoginResponse">
  <xs:complexType>
    <xs:sequence>
      <xs:element xmlns:q2="http://www.UKMail.com/Services/Contracts/DataContracts" minOccurs="0" name="LoginResult" nillable="true" type="q2:UKMLoginResponse"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

,其中包含一个名为的元素LoginResult,其类型为UKMLoginResponse

<xs:complexType name="UKMLoginResponse">
  <xs:complexContent mixed="false">
    <xs:extension base="tns:UKMWebResponse">
      <xs:sequence>
        <xs:element minOccurs="0" name="Accounts" nillable="true" type="tns:ArrayOfAccountWebModel"/>
        <xs:element name="AuthenticationToken" nillable="true" type="xs:string"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

UKMLoginResponse有两个自己Accounts的 typeArrayOfAccountWebModelAuthenticationTokenof typeString元素,以及另外三个继承自type 、of type和of typeUKMWebResponse的元素(注意extension语句):ErrorsArrayOfUKMWebErrorWarningsArrayOfUKMWebWarningResultUKMResultState

<xs:complexType name="UKMWebResponse">
  <xs:sequence>
    <xs:element minOccurs="0" name="Errors" nillable="true" type="tns:ArrayOfUKMWebError"/>
    <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/UKMWebAPICommon.WebResponses" name="Result" type="q1:UKMResultState"/>
    <xs:element minOccurs="0" name="Warnings" nillable="true" type="tns:ArrayOfUKMWebWarning"/>
  </xs:sequence>
</xs:complexType>

在该工具生成的工件中,wsimport它看起来像这样:

public class UKMLoginResponse extends UKMWebResponse { ... }

因此,为了从 中获取身份验证令牌LoginResponse,我们执行以下操作:

$LoginResponse = $soapClient->Login($Login);
$AuthenticationToken = $LoginResponse->LoginResult->AuthenticationToken;

调用方法

我不会在这里很具体,因为它与我们上面所做的非常相似。

例如,让我们调用一个AddDomesticConsignment()方法。根据寄售服务的 WSDL 文档,$soapClient->__getFunctions()AddDomesticConsignment()方法返回的结果采用一个$parameterstype 的参数,AddDomesticConsignment并返回一个 type 的结果AddDomesticConsignmentResponse。通过分析AddDomesticConsignment复杂类型,我们看到它有一个名为request类型的元素AddDomesticConsignmentWebRequestextendsAddConsignmentWebRequest本身 extends WebRequest。以下是该AddDomesticConsignmentWebRequest类型的所有元素的列表:

// AddDomesticConsignmentWebRequest's own elements
boolean BookIn
decimal CODAmount
string ConfirmationEmail
string ConfirmationTelephone
boolean ExchangeOnDelivery
int ExtendedCover
boolean LongLength
PreDeliveryNotificationType PreDeliveryNotification
string SecureLocation1
string SecureLocation2
boolean SignatureOptional

// elements inhereted from AddConsignmentWebRequest
string AccountNumber
AddressWebModel Address
string AlternativeRef
string BusinessName
string CollectionJobNumber
boolean ConfirmationOfDelivery
string ContactName
string CustomersRef
string Email
int Items
int ServiceKey
string SpecialInstructions1
string SpecialInstructions2
string Telephone
decimal Weight

// elements inhereted from WebRequest
string Username
string AuthenticationToken

请注意,并非所有元素都是必需的。那些可选的minOccurs属性0在 XML Schema 中设置为。

<xs:element minOccurs="0" name="PreDeliveryNotification" type="tns:PreDeliveryNotificationType"/>

所以,最终这就是我们调用该方法的方式:

$AddDomesticConsignmentWebRequest = new stdClass();
$AddDomesticConsignmentWebRequest->Username = 'Username';
// setting the Authentication Token from the previous step
$AddDomesticConsignmentWebRequest->AuthenticationToken = $AuthenticationToken;
// other properties are set here...

$AddDomesticConsignment = new stdClass();
$AddDomesticConsignment->request = $AddDomesticConsignmentWebRequest;

$soapClient = new SoapClient('https://qa-api.ukmail.com/Services/UKMConsignmentServices/UKMConsignmentService.svc?wsdl');
$AddDomesticConsignmentResponse = $soapClient->AddDomesticConsignment($AddDomesticConsignment);

AddDomesticConsignmentResponse解析为我们根据LoginResponseXML Schema 文档中的定义解析 。

好吧,我想这就是全部。我自己没有尝试过,但理论上它应该可以工作。希望这可以帮助。

更新

根据跟踪货物的文件,应该像执行以下操作一样简单:

// create the SOAP client
$soapClient = new SoapClient('http://web-service/?wsdl');
// call the `ConsignmentTrackingSearchV1` method and pass the search parameters
$ConsignmentTrackingSearchV1Response = $soapClient->ConsignmentTrackingSearchV1(
    'mail.com', // Username
    '123',      // Password
    '',         // Token
    '01161',    // ConsignmentNumber
    'false',    // IsPartialConsignmentNumber
    '',         // CustomerReference
    'false'     // IsPartialCustomerReference
    '',         // DeliveryPostCode
    '',         // MailingID
    100         // MaxResults
);
// parse the response
$ConsignmentTrackingSearchV1Result = $ConsignmentTrackingSearchV1Response->ConsignmentTrackingSearchV1Result;
$ResultState = $ConsignmentTrackingSearchV1Result->ResultState; // Successful
$ConsignmentResults = $ConsignmentTrackingSearchV1Result->ConsignmentResults;
// loop through the `ConsignmentResults`
foreach ($ConsignmentResults as $ConsignmentSearchResult) {
    $ConsignmentNumber = $ConsignmentSearchResult->ConsignmentNumber;
    $ConsignmentStatus = $ConsignmentSearchResult->ConsignmentStatus;
    // other properties
}

就是这样!

于 2012-05-11T15:46:34.440 回答
3

好吧,zafarkhaja 先生帮了我很多,但对于像我这样的其他人,我想解释一下什么对我有用,这样将来也可能对其他人有帮助..

用于处理复杂类型 例如就像在我的 Uk Mail Api For login 我这样做了

$LoginWebRequest = new stdClass();
$LoginWebRequest->Username = 'username';
$LoginWebRequest->Password = 'password';



$Login = new stdClass();
$Login->loginWebRequest = $LoginWebRequest;



$soapClient = new SoapClient('somewsdl?wsdl', array('cache_wsdl' => WSDL_CACHE_NONE) );


$LoginResponse = $soapClient->Login($Login);

万岁,我可以登录了。它给了我一个我需要检索的回应

 $AuthenticationToken = $LoginResponse->LoginResult->AuthenticationToken; 

我得到了身份验证令牌,确定您可以根据您的网络服务更改参数

当您不处理复杂类型时,使用肥皂客户端很好

   $soapClient = new SoapClient('http://somewsdl?wsdl');

    //create an array whose valuse will be passed has parameters
          $input_array = array (   
               UserName => 'username',
               Password => 'password'

     ) ;

    // passes our array
    $ConsignmentResponse = $soapClient1->TrackingSearch($input_array);

  //retrieve the response like this 

    $ResultState =  $ConsignmentResponse->ResultState; // Successful

好吧,我到处搜索,但没有人发布任何有效的示例,所有代码在 php soap 1.1 中都适用于我,无论是复杂类型还是没有。

于 2012-05-23T07:28:44.233 回答