在使用Savon.rb的Rails项目中,我试图进行非常复杂的SOAP调用。至少对于Savon构建器来说太复杂了,所以我决定直接操纵:xml。
我添加了一个正确格式化的
以下是Savon在此情况下实际进行的调用,使用
似乎有一个主要问题(顺便说一下,使用Savon构建器时也是如此),即
我告诉Savon按照我的xml构建它,但它不起作用。直接发送我的版本会返回错误400。
编辑Chris的部分后,我能够进行以下调用:
设置调用
首先,我初始化客户端:
@client = Savon.client(
:endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc',
:wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl')
我接下来的操作是以以下形式进行调用:
@request = @client.build_request(:generate_barcode,
xml: %Q{ ... see soap call (with ruby interpolation) ... }
我添加了一个正确格式化的
l Time.now,format::postnl_api
字符串,其余部分仍然是硬编码的。包括消息编号。以下是Savon在此情况下实际进行的调用,使用
@request.body
检索。
我的应用程序中的SOAP调用
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://tempuri.org/"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode
</Action>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<UsernameToken>
<Username>devc_!R4xc8p9</Username>
<Password>xxxxxxxx</Password>
</UsernameToken>
</Security>
</s:Header>
<s:Body>
<wsdl:GenerateBarcode>
<d6p1:Customer>
<d6p1:CustomerCode>DEVC</d6p1:CustomerCode>
<d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
</d6p1:Customer>
<d6p1:Barcode>
<d6p1:Type>3S</d6p1:Type>
<d6p1:Range>DEVC</d6p1:Range>
<d6p1:Serie>1000000-2000000</d6p1:Serie>
</d6p1:Barcode>
</wsdl:GenerateBarcode>
</s:Body>
</s:Envelope>
接下来是我在公司沙盒环境中看到成功的呼叫方式。
正确的SOAP调用方式
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode</Action>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Username>devc_!R4xc8p9</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">xxxxxxxx</wsse:Password>
</wsse:UsernameToken>
</Security>
</s:Header>
<s:Body>
<GenerateBarcode xmlns:d6p1="http://postnl.nl/cif/domain/BarcodeWebService/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://postnl.nl/cif/services/BarcodeWebService/">
<d6p1:Message>
<d6p1:MessageID>5</d6p1:MessageID>
<d6p1:MessageTimeStamp>28-06-2017 14:15:41</d6p1:MessageTimeStamp>
</d6p1:Message>
<d6p1:Customer>
<d6p1:CustomerCode>DEVC</d6p1:CustomerCode>
<d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
</d6p1:Customer>
<d6p1:Barcode>
<d6p1:Type>3S</d6p1:Type>
<d6p1:Range>DEVC</d6p1:Range>
<d6p1:Serie>1000000-2000000</d6p1:Serie>
</d6p1:Barcode>
</GenerateBarcode>
</s:Body>
</s:Envelope>
似乎有一个主要问题(顺便说一下,使用Savon构建器时也是如此),即
envelope
的属性和主操作的:generate_barcode
形状以及其属性。我不明白为什么在GenerateBarcode
之前会出现前缀wsdl:
。我告诉Savon按照我的xml构建它,但它不起作用。直接发送我的版本会返回错误400。
编辑Chris的部分后,我能够进行以下调用:
设置调用
@client = Savon.client(
:endpoint => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/BarcodeWebService.svc',
:wsdl => 'https://testservice.postnl.com/CIF_SB/BarcodeWebService/1_1/?wsdl',
:log => true,
:wsse_auth => [ENV['postnl_username'], ENV['postnl_password']],
:pretty_print_xml => true,
:convert_request_keys_to => :camelcase,
:env_namespace => :s)
message = {
"d6p1:Message" => {
"d6p1:MessageID" => "7",
"d6p1:MessageTimeStamp" => I18n.l( Time.now, format: :postnl_api)
},
"d6p1:Customer" => {
"d6p1:CustomerCode" => "DEVC",
"d6p1:CustomerNumber" => "11223344"},
"d6p1:Barcode" => {
"d6p1:Type" => "3S",
"d6p1:Range" => "DEVC",
"d6p1:Serie" => "1000000-2000000" }
}
@client.call(:generate_barcode, :message => message, :soap_header => { "Action" => "http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode"})
调用
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://tempuri.org/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action>http://postnl.nl/cif/services/BarcodeWebService/IBarcodeWebService/GenerateBarcode</Action>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-1">
<wsse:Username>devc_!R4xc8p9</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">098fd559930983af31ef6630a0bb0c1974156561</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
<s:Body>
<wsdl:GenerateBarcode>
<d6p1:Message>
<d6p1:MessageID>7</d6p1:MessageID>
<d6p1:MessageTimeStamp>17-07-2017 22:13:35</d6p1:MessageTimeStamp>
</d6p1:Message>
<d6p1:Customer>
<d6p1:CustomerCode>DEVC</d6p1:CustomerCode>
<d6p1:CustomerNumber>11223344</d6p1:CustomerNumber>
</d6p1:Customer>
<d6p1:Barcode>
<d6p1:Type>3S</d6p1:Type>
<d6p1:Range>DEVC</d6p1:Range>
<d6p1:Serie>1000000-2000000</d6p1:Serie>
</d6p1:Barcode>
</wsdl:GenerateBarcode>
</s:Body>
</s:Envelope>
响应:
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-US">The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>