我试图重写由savon body namespace写的 - ins0
我有这个客户端变量:
client = Savon.client(wsdl: "https://integcert.synxis.com/interface/Contracts/ChannelConnect2004.wsdl", log_level: :debug, log: true, pretty_print_xml: true, env_namespace: :soapenv, namespaces: {"xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:head": "http://htng.org/1.1/Header/","xmlns:ns": "http://www.opentravel.org/OTA/2003/05"}, convert_request_keys_to: :none, namespace_identifier: "ns", element_form_default: :qualified)
当Am在做请求时:
client.call(:ping, soap_header: { "head:HTNGHeader": { "head:From": { "head:Credential": { "head:userName": "******", "head:password":"*****" }}}}, message: {"ns:EchoData": "TestData"})
我有这个肥皂rq身体:
<soapenv:Body>
<ins0:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ins0:OTA_PingRQ>
</soapenv:Body>
这个ins0来自哪里?
当我尝试使用namespace_identifier: nil
参数定义客户端并执行此类请求时:
client.call(:ping, soap_header: { "head:HTNGHeader": { "head:From": { "head:Credential": { "head:userName": "******", "head:password":"*****" }}}}, message: {"ns:OTA_PingRQ": {"ns:EchoData": "TestData"}})
我有这个肥皂rq身体:
<soapenv:Body>
<OTA_PingRQ>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</OTA_PingRQ>
我想拥有的正确身体是:
<soapenv:Body>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</soapenv:Body>
如何删除其他嵌套OTA_PingRQ
节点或用自定义替换ins0
命名空间?
答案 0 :(得分:2)
您对其他命名空间的想法在逻辑上是正确的,但看起来Savon并不想在任何地方使用它们。它更喜欢使用WSDL中的命名空间。我尝试了element_form_default: :qualified
和element_form_default: :unqualified
,但每次都会将ins0
作为OTA_PingRQ
节点的命名空间。我想如果它想要ins0
那么让我们使用ins0
。
我查看了可用名称空间列表,并找到了适合标题的名称空间。不知道为什么Savon不想自动为头节点指定命名空间,所以我们必须手动指定它为ins1
。
以下是配置的工作版本:
client = Savon.client(
wsdl: "https://integcert.synxis.com/interface/Contracts/ChannelConnect2004.wsdl",
log_level: :debug,
log: true,
pretty_print_xml: true,
namespace_identifier: :ins0,
element_form_default: :qualified,
soap_header: {
"ins1:HTNGHeader": {
"ins1:From": {
"ins1:Credential": {
"ins1:userName": "******",
"ins1:password":"*****"
}
}
}
}
)
client.call(:ping, message: {"EchoData": "TestData"})
请求:
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ins0="http://www.opentravel.org/OTA/2003/05" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins1="http://htng.org/1.1/Header/">
<env:Header>
<ins1:HTNGHeader>
<ins1:From>
<ins1:Credential>
<ins1:userName>******</ins1:userName>
<ins1:password>*****</ins1:password>
</ins1:Credential>
</ins1:From>
</ins1:HTNGHeader>
</env:Header>
<env:Body>
<ins0:OTA_PingRQ>
<ins0:echoData>TestData</ins0:echoData>
</ins0:OTA_PingRQ>
</env:Body>
</env:Envelope>
响应:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<OTA_PingRS xmlns="http://www.opentravel.org/OTA/2003/05" PrimaryLangID="en">
<Errors>
<Error Type="4" ShortText="Login failed"/>
</Errors>
<EchoData/>
</OTA_PingRS>
</soap:Body>
</soap:Envelope>
编辑:在客户端配置中提供soap_header
,因为它更有效。
答案 1 :(得分:0)
还有另一种附加namespace_identifier的方法。 首先在 Savon 客户端设置 namespace_identifier: nil。
basic_auth = [username, password]
client = Savon.client(
wsdl:"https://integcert.synxis.com/interface/ChannelConnect2004.wsdl",
namespace: {},
env_namespace: 'soapenv',
namespace_identifier: nil,
basic_auth: basic_auth,
logger: Rails.logger,
log: true,
soap_version: 2,
pretty_print_xml: true,
convert_request_keys_to: :camelcase,
namespaces: {
'xmlns:soap' => 'http://example.com/soap-envelope',
'xmlns:glob' => 'http://example.com/Global'
}
)
现在同时调用操作集message_tag response = client.call(:operation_name, message_tag: 'glob:OTA_PingRQ', message: {"EchoData": "TestData"})
输出:
<soapenv:Body>
<glob:OTA_PingRQ>
<EchoData>TestData</ns:EchoData>
</glob:OTA_PingRQ>
</soapenv:Body>
For Outoput like:
<soapenv:Body>
<ns:OTA_PingRQ>
<ns:EchoData>TestData</ns:EchoData>
</ns:OTA_PingRQ>
</soapenv:Body>
client call will be same but in client config add **element_form_default: :qualified**