8


4

RubyのSOAP通信にsavonを使用するときに、「wsdl」名前空間がアクション名に挿入されるのはなぜですか?

制御できないSOAPサービスにアクセスしようとしています。 アクションの1つは「ProcessMessage」と呼ばれます。 例に従ってSOAPリクエストを生成しましたが、アクションが存在しないというエラーが返されました。 問題の原因は、エンベロープの本体の生成方法にあります。

                USER
                    658e702d5feff1777a6c741847239eb5d6d86e48
                    2010-02-18T02:05:25Z
                    password






                ......

その `ProcessMessage`タグは次のようになります。


それは、サンプルJavaアプリによって生成されたときのものであり、動作します。 このタグは、Rubyアプリが生成するものとサンプルJavaアプリとの唯一の違いです。 その1つのタグの前にある `" wsdl: "`名前空間を削除し、そのような属性を追加する方法はありますか。 それを除いて、体の残りの部分のような文字列として渡されるだけでアクションが生成されないように強制する方法はありますか?

これが私のコードです:

require 'rubygems'
require 'savon'
client = Savon::Client.new "https://gmservices.pp.gm.com/ProcessMessage?wsdl"

response = client.process_message! do | soap, wsse |
wsse.username = "USER"
wsse.password = "password"
soap.namespace = "http://www.starstandards.org/webservices/2005/10/transport" #makes no difference
soap.action = "ProcessMessage" #makes no difference
soap.input = "ProcessMessage" #makes no difference

#my body at this point is jsut one big xml string

soap.body = "..."
# putting  tag here doesn't help as it just creates a duplicate tag in the body, since Savon keeps interjecting   tag.

  end

私はhandsoapを試してみましたが、HTTPSをサポートしておらず、混乱しています。 soap4rを試しましたが、handsoapよりもさらに混乱します。

3 Answer


10


配列をsoap.inputに渡す必要があり、その2番目の要素は名前空間の詳細を含むハッシュです。

soap.input = [
  "ProcessMessage",
  {"xmlns" => "http://www.starstandards.org/webservices/2005/10/transport"}
]

これにより、メイン要素の属性として名前空間の宣言が行われるようになります。

また、おそらくそのような要素の前に名前空間宣言で終わるでしょう

            ......

しかし、これは私にとって問題ではありませんでした。それは問題である名前空間属性の欠如であり、要素の前の名前空間の存在ではありませんでした。


7


私のWebサービスでは、Steveのソリューションの上にある `" wsdl "`名前空間を削除する必要がありました。

Savon 0.9.6でテスト済み:

client = Savon::Client.new "https://example.com/webservice/account.asmx?WSDL"
response = client.request "GetAccount" do
  # Gotcha 1: set default namespace for body elements
  soap.input = ["GetAccount", {"xmlns" => "https://example.com/webservice/"}]
  soap.body = {
    "AccountID" => 1234
  }
  # Gotcha 2: get rid of namespace declaration of body elements
  soap.element_form_default = :unqualified
  # Gotcha 3: set SOAPAction different from default
  http.headers["SOAPAction"] = '"https://example.com/webservice/GetAccount"'
end


4


スティーブ、wsdl:ProcessMessageタグの前にあるのがわかりますか? -私はそれが私を投げ捨てた唯一のものであると思っていましたが、そうではありませんでした(ところで、160行目のSavon libのsoap.rbで難しい設定になっています)。 それをsoap.namespacesでspacifyしなくても-それはハード生成され、最終的なxmlに添付されます。 これは私のサービスでは許可されていません。

生成されたxmlは有効なxmlですが、話をしようとしているサービスの要件では完全ではありません。 つまり、生成されたxmlで、


タグが欠落している、また、ヘッダーにPayloadManifestが必要です。さらに、wsse:タグにwsu:createdおよびwsu:expiresが必要ですが、実装されていません。など。 私の場合に特有すぎる、他の小さな癖の束。 ただし、soapにはprivateメソッド= xml_bodyがあります。 また、to_xmlメソッドのsoap libは、独自のxmlを生成する前に@xml_bodyがすでに設定されているかどうかをチェックしています。 だから、石鹸の動作を少し変更することになりました。 soap.xml_body =パブリックにアクセス可能にします。 だから私はできました:

response = client.process_message! do |soap|
soap.action = "http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage"
soap.xml_body = "MY XML STRING GENERATED ELSEWHERE GOES HERE"
end

ついに機能します!!!!

私はこれをrubiiに提案します-このオプションが利用可能になり、多くのまれなケースを解決する場合-人々がカスタムxmlを生成し、savon libの残りを使用することができます。