2016-02-24 99 views
0

我正在編寫基於Salesforce的Web應用程序的客戶端(iOS,Swift),並且需要通過SOAP訪問自定義API。無法手動編寫來自WSDL的簡單SOAP請求

我正在努力根據從服務器端收到的WSDL手動組裝SOAP請求。

我對XML/SOAP完全沒有經驗,現在剛開始瞭解整個WSDL的內容。我已閱讀thisthis以及其他介紹性在線文檔,但我仍在努力掌握所有新概念。由於保密原因(暴露了我的web應用程序的內部),我不願意使用任何在線自動生成器,如this one


這是我的WSDL的相關(我認爲)部分:

<definitions targetNamespace="http://soap.sforce.com/schemas/class/[WSDL_File_Name]" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://soap.sforce.com/schemas/class/[WSDL_File_Name]"> 

    <!-- ... --> 

    <message name="executeXmlRequest"> 
     <part name="parameters" element="tns:executeXml" /> 
    </message> 

    <!-- ... --> 

    <binding name="[WSDL_File_Name]Binding" type="tns:[WSDL_File_Name]PortType"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 
     <operation name="executeXml"> 
      <soap:operation soapAction=""/> 
       <input> 
        <soap:header use="literal" part="SessionHeader" message="tns:Header"/> 
        <soap:header use="literal" part="CallOptions" message="tns:Header"/> 
        <soap:header use="literal" part="DebuggingHeader" message="tns:Header"/> 
        <soap:header use="literal" part="AllowFieldTruncationHeader" message="tns:Header"/> 
        <soap:body use="literal" parts="parameters"/> 
       </input> 
       <output> 
        <!-- skipped --> 
       </output> 
     </operation> 
    </binding> 
<service name="[WSDL_File_Name]Service"> 
    <documentation></documentation> 
     <port binding="tns:[WSDL_File_Name]Binding" name="[WSDL_File_Name]"> 
      <soap:address location="https://XXX.salesforce.com/services/Soap/class/[WSDL_File_Name]"/> 
     </port> 
</service> 

(我已經模糊[WSDL_File_Name] WSDL文件的-the名,這也發生作爲前綴這裏和那裏)。

尤其我不太懂其中的消息部分:

<message name="executeXmlRequest"> 
    <part name="parameters" element="tns:executeXml" /> 
</message> 

在大多數例子,我發現在網絡上(如herehere),它通常是name="body""parameters"),所以我不確定如何將其轉換爲實際的SOAP請求的XML主體。我試過這個請求體:

<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com"> 
    <soapenv:Header> 
     <urn:SessionHeader> 
      <urn:sessionId>[My OAuth 2.0 Token]</urn:sessionId> 
     </urn:SessionHeader> 
    </soapenv:Header> 
    <soapenv:Body> 
     <tns:executeXml xmlns:tns="http://soap.sforce.com/schemas/class/[WSDL_File_Name]"> 

     <!-- PAYLOAD HERE (more XML) --> 

     </tns:executeXml> 
    </soapenv:Body> 
</soapenv:Envelope> 

...但我得到「參數1不能爲空」錯誤響應:

<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/schemas/class/[WSDL_File_Name]"> 
    <soapenv:Body> 
     <executeXmlResponse> 
      <result> 
      <!-- 
       The following inline-XML came from the server with 
       all entities escaped (e.g., "&lt;" instead of "<"); 
       I replaced them back here for legibility. 
      --> 
      <?xml version="1.0" encoding="UTF-8"?> 
      <response> 
       <success>false</success> 
       <exception> 
        <typeName>System.NullPointerException</typeName> 
        <message>Argument 1 cannot be null</message> 
        <stackTrace>Class.[Inbound_Service_Class].Message.<init>: line 271, column 1 
    Class.[Inbound_Service_Class].parse: line 47, column 1 
    Class.[Inbound_Service_Class].receive: line 29, column 1 
    Class.[WSDL_File_Name].executeXml: line 18, column 1 
        </stackTrace> 
       </exception> 
      </response> 
      <!-- 
       Originally escaped entitied end here 
      --> 
      </result> 
     </executeXmlResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

(再次,應用程序特定的類名/等在方括號中模糊化)

那麼,我的請求應該是什麼樣子?


澄清:出現字符串 「參數」(作爲XML屬性值)在整個WSDL文件共倍:

  1. 輸入消息:<message name="executeXmlRequest"><part name="parameters"...
  2. 輸出信息:<message name="executeXmlResponse"><part name="parameters"...
  3. 裝訂:<binding...> ... <soap:body use="literal" parts="parameters"/>...

SOLUTION:

通過this answer和內容指導重新讀取所有的文檔(例如,this page),我終於實現了tns:executeXml標籤的內容中被指定我的WSDL的類型部分(對不起,我沒有在我的問題中發佈這個部分。類型部分是巨大的,我跳過它完全):

<xsd:element name="executeXml"> 
    <xsd:complexType> 
    <xsd:sequence> 
     <xsd:element name="reqXml" type="xsd:string" nillable="true"/> 
         <!--^THIS GUY... --> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 

...所以我想,這轉化爲與身體信封這樣的SOAP請求:

<soapenv:Body> 
    <tns:executeXml xmlns:tns=\"http://soap.sforce.com/schemas/class/[WSDL_File_Name]"> 

     <!-- ...BECOMES THIS ELEMENT: --> 
     <tns:reqXml><!-- (MY ESCAPED XML PAYLOAD GOES HERE) --></tns:reqXml> 

    </tns:executeXml> 
</soapenv:Body> 

現在,我只是獲取有關我發佈的XML內容的應用程序特定錯誤消息,但我可以自行解決。我似乎成功地獲得了API。

對不起@Sundar我以前沒有提供足夠的信息。我已經接受了你的回答,因爲它讓我朝着正確的方向前進。

回答

2

使用像SOAPUI這樣的工具,有免費版本,將它指向WSDL並創建一個新的soap項目,然後可以創建一個帶有虛擬值的soap請求,並將其替換爲您的值。我們擁有完整的WSDL並不能說明請求xml中的內容,也就是說合同的關鍵點不在於它。

但你的錯誤似乎是非常具體的,你是不是不應該是空的特定參數發送一個空值,我覺得

+0

就像我說的,我不能指向一個免費的工具到WSDL。另外,我想我附加了我的WSDL的所有相關部分。基本上,我應該嵌入一些服務器端API將解析的XML,因此除了消息名稱和服務URL之外,沒有什麼可指定的東西......?我只是不確定「嵌入」它的確切格式(除了例如轉義實體等) –

+0

此外,我沒有一個URL,我的WSDL不在登錄屏幕後面(我認爲) 。我從控制面板中獲得了它。 –

+0

你有沒有wsdl文件,你可以指出,沒有辦法在沒有看到我的愚見的WSDL文件的情況下編寫請求 – Sundar