[英]Ruby Savon 2 error: Savon::SOAPFault ((SOAP-ENV:Server) The namespace prefix is not allowed to start with the reserved string "xml".)
我正在嘗試連接到一家使用 SOAP 遠程過程調用的公司,因此我使用的是 Savon Gem。 這是我必須設置身份驗證的內容:
require 'savon'
client = Savon.client(
wsdl: 'https://customdomain.companydomain.com:port/wsdlcode/wsdl/xmlBridge',
endpoint: 'https://customdomain.companydomain.com:port/endpointcode/soap/xmlBridge',
basic_auth: ["username", "password"],
env_namespace: :soapenv,
namespace_identifier: :web,
logger: Rails.logger,
log_level: :debug,
log: true,
:pretty_print_xml => true,
encoding: 'UTF-8'
)
這似乎有效。 我什至可以調用“client.operations”來獲取可以調用的函數列表。 當我跑步時
response = client.call(:get_active_employees)
嘗試獲取員工列表時,我收到錯誤消息:
Savon::SOAPFault ((SOAP-ENV:Server) The namespace prefix is not allowed to start with the reserved string "xml".)
有誰知道如何解決這一問題?
這里的問題是 wsdl 可能包含 Savon 自動添加到您在請求中發回的 xml 中的不正確命名空間。 如果您使用以下命令查看 Savon Gem 中的 lib/savon/builder.rb 文件: gem which savon
確定您的沙龍寶石所在的位置,然后打開您的 IDE 中的封閉寶石文件夾。這應該與/Users/username/.rvm/gems/ruby-2.5.1/gems/savon-2.13.0/
如果你在 Mac 上
打開 builder.rb 文件lib/savon/builder.rb
在這里你會看到一個方法命名空間,不幸的是它包含了 wsdl 中所有解析的命名空間:
@wsdl.parser.namespaces.each do |identifier, path|
next if namespaces.key?("xmlns:#{identifier}")
namespaces["xmlns:#{identifier}"] = path
end
end
如果 wsdl 包含一個無效的命名空間,它將在您執行調用時立即包含在 output 中。
要解決此問題,您需要在config/initializers/savon_monkey_patch.rb
中添加一個包含附加代碼的新文件:
Savon::Builder.class_eval do
private
def namespaces
@namespaces ||= begin
namespaces = Savon::Builder::SCHEMA_TYPES.dup
# check namespace_identifier
namespaces["xmlns#{namespace_identifier.nil? ? '' : ":#{namespace_identifier}"}"] =
@globals[:namespace] || @wsdl.namespace
# check env_namespace
namespaces["xmlns#{env_namespace && env_namespace != "" ? ":#{env_namespace}" : ''}"] =
Savon::Builder::SOAP_NAMESPACE[@globals[:soap_version]]
if @wsdl&.document
@wsdl.parser.namespaces.each do |identifier, path|
# this is to get rid of the xml namespaces that are invalid in a soap document
next if namespaces.key?("xmlns:#{identifier}") || identifier.match?(/^xml/)
namespaces["xmlns:#{identifier}"] = path
end
end
namespaces
end
end
end
關鍵行是identifier.match?(/^xml/)
,它將從您的傳出請求中排除以 xml 開頭的任何命名空間。 我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.