如何使用 Savon 进行包含命名空间的 SOAP 调用
How to make a SOAP call including namespace with Savon
我正在尝试连接到 this SOAP API. Specifically, I am trying to login via this login call。
文档指出我应该提出以下请求:
POST /service/replicatorV4.asmx HTTP/1.1
Host: demo12231.srv106.webshopdemo.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Login"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Login xmlns="http://tempuri.org/">
<username>string</username>
<password>string</password>
</Login>
</soap:Body>
</soap:Envelope>
当我在SoapUI 发出以下请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:Login>
<tem:username>Administrator</tem:username>
<tem:password>passw0rd12</tem:password>
</tem:Login>
</soapenv:Body>
</soapenv: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>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult>48594fe6-41fd-45f9-9f84-89ef8c247b85</LoginResult>
</LoginResponse>
</soap:Body>
</soap:Envelope>
但是,当我和 Savon 提出这样的请求时:
require 'savon'
client = Savon.client( :wsdl => "http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
:open_timeout => 100,
:read_timeout => 100,
:ssl_verify_mode => :none,
:log_level => :debug,
:log => false,
:logger => Rails.logger,
:convert_request_keys_to => :camelcase)
response = client.call(:login, :message => {:username => "Administrator", :password => "passw0rd12"})
然后我得到了这个不满意的回复:
#<Savon::Response:0x007ff78cfcc368
@globals=
#<Savon::GlobalOptions:0x007ff782fb8160
@option_type=:global,
@options=
{:encoding=>"UTF-8",
:soap_version=>1,
:namespaces=>{},
:logger=>
#<ActiveSupport::Logger:0x007ff78b136ea8
@default_formatter=
#<Logger::Formatter:0x007ff78b136e30 @datetime_format=nil>,
@formatter=
#<ActiveSupport::Logger::SimpleFormatter:0x007ff783e99f80
@datetime_format=nil>,
@level=0,
@logdev=
#<Logger::LogDevice:0x007ff78b136de0
@dev=
#<File:/Users/me/Projects/my_project/log/development.log>,
@filename=nil,
@mutex=
#<Logger::LogDevice::LogDeviceMutex:0x007ff78b136db8
@mon_count=0,
@mon_mutex=#<Mutex:0x007ff78b136d68>,
@mon_owner=nil>,
@shift_age=nil,
@shift_size=nil>,
@progname=nil>,
:log=>false,
:filters=>[],
:pretty_print_xml=>false,
:raise_errors=>true,
:strip_namespaces=>true,
:convert_response_tags_to=>
#<Proc:0x007ff782fc3e70@/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/savon-2.11.1/lib/savon/options.rb:85 (lambda)>,
:convert_attributes_to=>
#<Proc:0x007ff782fc3df8@/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/savon-2.11.1/lib/savon/options.rb:86 (lambda)>,
:multipart=>false,
:adapter=>nil,
:use_wsa_headers=>false,
:no_message_tag=>false,
:follow_redirects=>false,
:unwrap=>false,
:host=>nil,
:wsdl=>
"http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
:open_timeout=>100,
:read_timeout=>100,
:ssl_verify_mode=>:none,
:convert_request_keys_to=>:camelcase,
:endpoint=>
#<URI::HTTP:0x007ff78479cbf0 URL:http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx>}>,
@http=
#<HTTPI::Response:0x007ff78cfcd2b8
@body=
"<?xml version=\"1.0\" encoding=\"utf-8\"?><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><LoginResponse xmlns=\"http://tempuri.org/\"><LoginResult xsi:nil=\"true\" /></LoginResponse></soap:Body></soap:Envelope>",
@code=200,
@headers=
{"Cache-Control"=>"private, max-age=0",
"Content-Type"=>"text/xml; charset=utf-8",
"Server"=>"Microsoft-IIS/8.5",
"Date"=>"Thu, 27 Aug 2015 05:29:42 GMT",
"Content-Length"=>"335"},
@raw_body=
"<?xml version=\"1.0\" encoding=\"utf-8\"?><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><LoginResponse xmlns=\"http://tempuri.org/\"><LoginResult xsi:nil=\"true\" /></LoginResponse></soap:Body></soap:Envelope>">,
@locals=
#<Savon::LocalOptions:0x007ff78ce7f550
@option_type=:local,
@options=
{:advanced_typecasting=>true,
:response_parser=>:nokogiri,
:multipart=>false,
:message=>{:username=>"Administrator", :password=>"passw0rd12"},
:soap_action=>"http://tempuri.org/Login"}>>
响应的正文部分是:
{:login_response=>{:login_result=>nil, :@xmlns=>"http://tempuri.org/"}}
这告诉我,也许服务确实收到了整体请求,但没有获得变量。响应看起来很像我在 SoapUI 中使用错误的 username
和 password
:
发出此请求时的响应
<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>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult xsi:nil="true"/>
</LoginResponse>
</soap:Body>
</soap:Envelope>
我注意到变量中需要命名空间 tem
。这可能与我的问题有关吗?还是有别的解释?
创建一个没有 Rails 的纯 Ruby 脚本。
然后根据您使用 SoapUI 创建的内容检查输出。 Post 差异,有人会提供帮助。
当我 运行 这个脚本时:
require 'savon'
c = Savon.client(wsdl:
"http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
log_level: :debug,
log: true,
pretty_print_xml: true)
response = c.call(:login,
:message => {:username => "Administrator", :password => "passw0rd12"})
对我有用。它可能是你的 Rails 部分中的某些东西会干扰。我不这样做 Rails 因此我在那里帮不了什么忙(我更喜欢 Sinatra :-))。
我正在尝试连接到 this SOAP API. Specifically, I am trying to login via this login call。
文档指出我应该提出以下请求:
POST /service/replicatorV4.asmx HTTP/1.1
Host: demo12231.srv106.webshopdemo.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Login"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Login xmlns="http://tempuri.org/">
<username>string</username>
<password>string</password>
</Login>
</soap:Body>
</soap:Envelope>
当我在SoapUI 发出以下请求:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:Login>
<tem:username>Administrator</tem:username>
<tem:password>passw0rd12</tem:password>
</tem:Login>
</soapenv:Body>
</soapenv: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>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult>48594fe6-41fd-45f9-9f84-89ef8c247b85</LoginResult>
</LoginResponse>
</soap:Body>
</soap:Envelope>
但是,当我和 Savon 提出这样的请求时:
require 'savon'
client = Savon.client( :wsdl => "http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
:open_timeout => 100,
:read_timeout => 100,
:ssl_verify_mode => :none,
:log_level => :debug,
:log => false,
:logger => Rails.logger,
:convert_request_keys_to => :camelcase)
response = client.call(:login, :message => {:username => "Administrator", :password => "passw0rd12"})
然后我得到了这个不满意的回复:
#<Savon::Response:0x007ff78cfcc368
@globals=
#<Savon::GlobalOptions:0x007ff782fb8160
@option_type=:global,
@options=
{:encoding=>"UTF-8",
:soap_version=>1,
:namespaces=>{},
:logger=>
#<ActiveSupport::Logger:0x007ff78b136ea8
@default_formatter=
#<Logger::Formatter:0x007ff78b136e30 @datetime_format=nil>,
@formatter=
#<ActiveSupport::Logger::SimpleFormatter:0x007ff783e99f80
@datetime_format=nil>,
@level=0,
@logdev=
#<Logger::LogDevice:0x007ff78b136de0
@dev=
#<File:/Users/me/Projects/my_project/log/development.log>,
@filename=nil,
@mutex=
#<Logger::LogDevice::LogDeviceMutex:0x007ff78b136db8
@mon_count=0,
@mon_mutex=#<Mutex:0x007ff78b136d68>,
@mon_owner=nil>,
@shift_age=nil,
@shift_size=nil>,
@progname=nil>,
:log=>false,
:filters=>[],
:pretty_print_xml=>false,
:raise_errors=>true,
:strip_namespaces=>true,
:convert_response_tags_to=>
#<Proc:0x007ff782fc3e70@/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/savon-2.11.1/lib/savon/options.rb:85 (lambda)>,
:convert_attributes_to=>
#<Proc:0x007ff782fc3df8@/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/savon-2.11.1/lib/savon/options.rb:86 (lambda)>,
:multipart=>false,
:adapter=>nil,
:use_wsa_headers=>false,
:no_message_tag=>false,
:follow_redirects=>false,
:unwrap=>false,
:host=>nil,
:wsdl=>
"http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
:open_timeout=>100,
:read_timeout=>100,
:ssl_verify_mode=>:none,
:convert_request_keys_to=>:camelcase,
:endpoint=>
#<URI::HTTP:0x007ff78479cbf0 URL:http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx>}>,
@http=
#<HTTPI::Response:0x007ff78cfcd2b8
@body=
"<?xml version=\"1.0\" encoding=\"utf-8\"?><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><LoginResponse xmlns=\"http://tempuri.org/\"><LoginResult xsi:nil=\"true\" /></LoginResponse></soap:Body></soap:Envelope>",
@code=200,
@headers=
{"Cache-Control"=>"private, max-age=0",
"Content-Type"=>"text/xml; charset=utf-8",
"Server"=>"Microsoft-IIS/8.5",
"Date"=>"Thu, 27 Aug 2015 05:29:42 GMT",
"Content-Length"=>"335"},
@raw_body=
"<?xml version=\"1.0\" encoding=\"utf-8\"?><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><LoginResponse xmlns=\"http://tempuri.org/\"><LoginResult xsi:nil=\"true\" /></LoginResponse></soap:Body></soap:Envelope>">,
@locals=
#<Savon::LocalOptions:0x007ff78ce7f550
@option_type=:local,
@options=
{:advanced_typecasting=>true,
:response_parser=>:nokogiri,
:multipart=>false,
:message=>{:username=>"Administrator", :password=>"passw0rd12"},
:soap_action=>"http://tempuri.org/Login"}>>
响应的正文部分是:
{:login_response=>{:login_result=>nil, :@xmlns=>"http://tempuri.org/"}}
这告诉我,也许服务确实收到了整体请求,但没有获得变量。响应看起来很像我在 SoapUI 中使用错误的 username
和 password
:
<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>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult xsi:nil="true"/>
</LoginResponse>
</soap:Body>
</soap:Envelope>
我注意到变量中需要命名空间 tem
。这可能与我的问题有关吗?还是有别的解释?
创建一个没有 Rails 的纯 Ruby 脚本。
然后根据您使用 SoapUI 创建的内容检查输出。 Post 差异,有人会提供帮助。
当我 运行 这个脚本时:
require 'savon'
c = Savon.client(wsdl:
"http://demo12231.srv106.webshopdemo.net/service/replicatorV4.asmx?WSDL",
log_level: :debug,
log: true,
pretty_print_xml: true)
response = c.call(:login,
:message => {:username => "Administrator", :password => "passw0rd12"})
对我有用。它可能是你的 Rails 部分中的某些东西会干扰。我不这样做 Rails 因此我在那里帮不了什么忙(我更喜欢 Sinatra :-))。