簡體   English   中英

Ruby Savon 2 錯誤:Savon::SOAPFault ((SOAP-ENV:Server) 名稱空間前綴不允許以保留字符串“xml”開頭。)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM