无效的 SOAP 请求需要经验丰富的眼睛
invalid SOAP request needs experienced eye
TLDR:可以找到解决方案
我正在使用 savon 对 SOAP 服务发出请求。我知道...恶心。
无论如何,我无法让 Savon 乖乖听话。 SOAP 提供程序有 this 个验证器,它接受以下输入:
Web Service: ProductData
Version: 1.0.0
Operation: getProductSellable
Endpoint: https://psproductdata100-stg.pcna.online
当我使用验证器时,我输入这个xml:
<GetProductSellableRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<wsVersion xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">1.0.0</wsVersion>
</GetProductSellableRequest>
然后我得到了这个响应正文
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<code>110</code>
<description>Authentication Credentials Required</description>
</ErrorMessage>
</GetProductSellableResponse>
</s:Body>
</s:Envelope>
该回复有效,因为我没有提供 un/pw。如果我确实提供了凭据,我会得到完整的答复。下面是在我的浏览器中发生的截图。
但是,当我使用 Savon 提出相同的请求时
#!/usr/bin/env ruby
require 'savon'
require 'awesome_print'
require 'byebug'
require 'pry'
endpoint = 'https://psproductdata100-stg.pcna.online'
path = 'psProductData.svc?singleWsdl'
wsdl = "#{endpoint}/#{path}"
args = {
wsdl: wsdl,
log: true,
log_level: :debug,
pretty_print_xml: true,
element_form_default: :qualified
}
client = Savon.client(args) do
convert_request_keys_to :lower_camelcase
end
message = { ws_version: '1.0.0' }
response = client.call(:get_product_sellable) do
message(message)
end
ap response
响应没有按预期返回。 XML 看起来 接近 验证器发送的内容,但不准确。
这是请求
D, [2018-04-26T18:01:00.471662 #89854] DEBUG -- : HTTPI /peer GET request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:00.979809 #89854] INFO -- : SOAP request: https://psproductdata100-stg.pcna.online/psProductData.svc
I, [2018-04-26T18:01:00.979886 #89854] INFO -- : SOAPAction: "getProductSellable", Content-Type: text/xml;charset=UTF-8, Content-Length: 501
D, [2018-04-26T18:01:00.980107 #89854] DEBUG -- : <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<env:Body>
<tns:GetProductSellableRequest>
<tns:wsVersion>1.0.0</tns:wsVersion>
</tns:GetProductSellableRequest>
</env:Body>
</env:Envelope>
以及响应
D, [2018-04-26T18:01:00.980224 #89854] DEBUG -- : HTTPI /peer POST request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:01.650449 #89854] INFO -- : SOAP response (status 200)
D, [2018-04-26T18:01:01.650731 #89854] DEBUG -- : <?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<code>110</code>
<description>Version mismatch.</description>
</ErrorMessage>
</GetProductSellableResponse>
</s:Body>
</s:Envelope>
和 Savon 的输出
{
:get_product_sellable_response => {
:error_message => {
:code => "110",
:description => "Version mismatch.",
:@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"
},
:@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/"
},
:"@xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
:"@xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}
我认为您的问题是命名空间问题。 wsVersion 位于共享对象名称空间 "ins0" 内。它不在 "tns" 命名空间中。尝试将您的请求更改为如下所示:
<env:Body>
<tns:GetProductSellableRequest>
<ins0:wsVersion>1.0.0</ins0:wsVersion>
</tns:GetProductSellableRequest>
</env:Body>
命名空间存在类似问题 。我相信你也有同样的问题。
附加说明:尝试使用 SOAP UI 进行调试,从 WSDL 生成 XML 并查看差异。同时将 XML 更改为从代码生成的 XML 并验证 SOAP UI 中的 XML。如果 SOAP 中有错误,它将显示错误 UI,这将使调试速度更快,错误更容易理解。
多亏了此线程中的其他答案,我找到了 post。我阅读了有关名称空间如何工作以及链接的 XSD 文件的信息。通过将我的新知识与 post 相结合,我能够构建出如下内容:
require 'savon'
require 'awesome_print'
require 'byebug'
require 'pry'
endpoint = 'https://psproductdata100-stg.pcna.online'
path = 'psProductData.svc?singleWsdl'
wsdl = "#{endpoint}/#{path}"
args = {
wsdl: wsdl,
log: false,
log_level: :debug,
pretty_print_xml: true,
element_form_default: :qualified
}
client = Savon.client(args) do
convert_request_keys_to :lower_camelcase
namespaces 'xmlns:shar' => 'http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/'
end
message = {
'shar:wsVersion' => '1.0.0',
'shar:id' => 'REDACTED',
'shar:password' => 'REDACTED'
}
response = client.call(:get_product_sellable) do
message(message)
end
ap response.body[:get_product_sellable_response][:product_sellable_array][:product_sellable][0..2]
现在在晚宴上和我聊天更有趣了。
TLDR:可以找到解决方案
我正在使用 savon 对 SOAP 服务发出请求。我知道...恶心。
无论如何,我无法让 Savon 乖乖听话。 SOAP 提供程序有 this 个验证器,它接受以下输入:
Web Service: ProductData
Version: 1.0.0
Operation: getProductSellable
Endpoint: https://psproductdata100-stg.pcna.online
当我使用验证器时,我输入这个xml:
<GetProductSellableRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<wsVersion xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">1.0.0</wsVersion>
</GetProductSellableRequest>
然后我得到了这个响应正文
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<code>110</code>
<description>Authentication Credentials Required</description>
</ErrorMessage>
</GetProductSellableResponse>
</s:Body>
</s:Envelope>
该回复有效,因为我没有提供 un/pw。如果我确实提供了凭据,我会得到完整的答复。下面是在我的浏览器中发生的截图。
但是,当我使用 Savon 提出相同的请求时
#!/usr/bin/env ruby
require 'savon'
require 'awesome_print'
require 'byebug'
require 'pry'
endpoint = 'https://psproductdata100-stg.pcna.online'
path = 'psProductData.svc?singleWsdl'
wsdl = "#{endpoint}/#{path}"
args = {
wsdl: wsdl,
log: true,
log_level: :debug,
pretty_print_xml: true,
element_form_default: :qualified
}
client = Savon.client(args) do
convert_request_keys_to :lower_camelcase
end
message = { ws_version: '1.0.0' }
response = client.call(:get_product_sellable) do
message(message)
end
ap response
响应没有按预期返回。 XML 看起来 接近 验证器发送的内容,但不准确。
这是请求
D, [2018-04-26T18:01:00.471662 #89854] DEBUG -- : HTTPI /peer GET request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:00.979809 #89854] INFO -- : SOAP request: https://psproductdata100-stg.pcna.online/psProductData.svc
I, [2018-04-26T18:01:00.979886 #89854] INFO -- : SOAPAction: "getProductSellable", Content-Type: text/xml;charset=UTF-8, Content-Length: 501
D, [2018-04-26T18:01:00.980107 #89854] DEBUG -- : <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<env:Body>
<tns:GetProductSellableRequest>
<tns:wsVersion>1.0.0</tns:wsVersion>
</tns:GetProductSellableRequest>
</env:Body>
</env:Envelope>
以及响应
D, [2018-04-26T18:01:00.980224 #89854] DEBUG -- : HTTPI /peer POST request to psproductdata100-stg.pcna.online (net_http)
I, [2018-04-26T18:01:01.650449 #89854] INFO -- : SOAP response (status 200)
D, [2018-04-26T18:01:01.650731 #89854] DEBUG -- : <?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetProductSellableResponse xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/">
<ErrorMessage xmlns="http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/">
<code>110</code>
<description>Version mismatch.</description>
</ErrorMessage>
</GetProductSellableResponse>
</s:Body>
</s:Envelope>
和 Savon 的输出
{
:get_product_sellable_response => {
:error_message => {
:code => "110",
:description => "Version mismatch.",
:@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/"
},
:@xmlns => "http://www.promostandards.org/WSDL/ProductDataService/1.0.0/"
},
:"@xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
:"@xmlns:xsd" => "http://www.w3.org/2001/XMLSchema"
}
我认为您的问题是命名空间问题。 wsVersion 位于共享对象名称空间 "ins0" 内。它不在 "tns" 命名空间中。尝试将您的请求更改为如下所示:
<env:Body>
<tns:GetProductSellableRequest>
<ins0:wsVersion>1.0.0</ins0:wsVersion>
</tns:GetProductSellableRequest>
</env:Body>
命名空间存在类似问题
附加说明:尝试使用 SOAP UI 进行调试,从 WSDL 生成 XML 并查看差异。同时将 XML 更改为从代码生成的 XML 并验证 SOAP UI 中的 XML。如果 SOAP 中有错误,它将显示错误 UI,这将使调试速度更快,错误更容易理解。
多亏了此线程中的其他答案,我找到了
require 'savon'
require 'awesome_print'
require 'byebug'
require 'pry'
endpoint = 'https://psproductdata100-stg.pcna.online'
path = 'psProductData.svc?singleWsdl'
wsdl = "#{endpoint}/#{path}"
args = {
wsdl: wsdl,
log: false,
log_level: :debug,
pretty_print_xml: true,
element_form_default: :qualified
}
client = Savon.client(args) do
convert_request_keys_to :lower_camelcase
namespaces 'xmlns:shar' => 'http://www.promostandards.org/WSDL/ProductDataService/1.0.0/SharedObjects/'
end
message = {
'shar:wsVersion' => '1.0.0',
'shar:id' => 'REDACTED',
'shar:password' => 'REDACTED'
}
response = client.call(:get_product_sellable) do
message(message)
end
ap response.body[:get_product_sellable_response][:product_sellable_array][:product_sellable][0..2]
现在在晚宴上和我聊天更有趣了。