我该如何解决"意外的编码风格"使用Savon Gem和Ruby on Rails

时间:2016-05-24 22:34:27

标签: web-services soap wsdl savon

访问WSDL SOAP服务器时出现以下错误:

{:error=>true, :message=>"Savon::SOAPFault: (env:Client) JAXRPCTIE01: caught exception while handling request: unexpected encoding style: expected=http://schemas.xmlsoap.org/soap/encoding/, actual="}

我去了soapclient.com找出它想要的东西。

这是error message I'm receiving。 以下是我用来连接SOAP客户端的代码:

  my_hash_of_stuff = {
      zipcode: d_zip,
      country: country
  }

  wsdl = 'http://my.yrc.com/dynamic/national/WebServices/YRCZipFinder_V1.wsdl'

  client = Savon.client(wsdl: wsdl,
                        logger: Rails.logger,
                        log_level: :debug,
                        log: true,
                        pretty_print_xml: true,
                        env_namespace: :'soap-env',
                        strip_namespaces: true

  )


  response = client.call(:lookup_zip, message: my_hash_of_stuff)

  print response.to_hash

这是我log output 的副本,因此您可以看到发生了什么。

根据soapclient.com,

This似乎是SOAP请求的样子(如果我正确理解它)。

This就是我发送的内容。

我整天都在与它斗争,我确信它可能是我的无知和我失踪的简单事物的结合。希望你们能帮忙吗?

编辑05/25/2016: 所以,今天再看一遍,这里的日志显示了savon的要求:

HTTPI GET request to my.yrc.com (net_http)
SOAP request: http://my.yrc.com/dynamic/national/webservice/YRCZipFinder_V1
SOAPAction: "http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl/lookupCity", Content-Type: text/xml;charset=UTF-8, Content-Length: 417
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <tns:lookupCity>
      <zipCode>84101</zipCode>
      <country>USA</country>
    </tns:lookupCity>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

这是一个正确的样子。我从现有的php应用程序中得到了这个并在Postman中测试它以验证它是否有效:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://my.yrc.com/national/WebServices/YRCZipFinderMessages_V1.xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:lookupCity>
            <lookupCityRequest xsi:type="ns2:YRCLookupCityRequest">
                <zipCode xsi:type="xsd:string">84101</zipCode>
                <country xsi:type="ns2:CountryCode">USA</country>
            </lookupCityRequest>
        </ns1:lookupCity>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

更新

经过多次黑客攻击后,我的请求看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my.yrc.com/national/WebServices/YRCZipFinder_V1.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://my.yrc.com/national/WebServices/YRCZipFinderMessages_V1.xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <tns:lookupCity lookupCityRequest="ns2:YRCLookupCityRequest">
      <zipCode>84101</zipCode>
      <country>USA</country>
    </tns:lookupCity>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

但是,我需要让lookupCityRequest移到lookupCity内,而不是lookupCity的属性。在Postman中进行测试,这似乎是留下障碍的唯一绊脚石。

1 个答案:

答案 0 :(得分:0)

您可以使用特殊:attribute!符号分配其他属性。这是来自Nokogiri的功能,Savon用它来构建XML。

require 'savon'

my_hash_of_stuff = 
  { zipcode: "99103",
    country: 'US',
    attributes!: { :country => { 'xsi:type' => 'ns2:YRCLookupCityRequest'},
                   :zipcode => { 'xsi:type' => 'ns2:YRCLookupCityRequest' }}
}


wsdl = 'http://my.yrc.com/dynamic/national/WebServices/YRCZipFinder_V1.wsdl'

client = Savon.client(wsdl: wsdl,
                      # logger: Rails.logger,
                      log_level: :debug,
                      log: true,
                      pretty_print_xml: true,
                      env_namespace: :'soap-env',
                      strip_namespaces: true
)

response = client.call(:lookup_zip,
                       message: my_hash_of_stuff)

print response.to_hash

如果没有任何效果且您非常绝望,那么您仍然可以创建自己的XML并使用xml:代替message: