Savon2请求体多命名空间传递问题求助
嘿,刚上手Savon2遇到多命名空间的问题很正常,我来给你捋清楚怎么搞定它~
首先,你得先搞清楚WSDL里定义的各个命名空间——每个请求元素对应的targetNamespace是什么,这是关键。然后我们可以通过两种主要方式在Savon里处理多命名空间:
第一步:在客户端配置中定义命名空间别名
先修改你的客户端初始化代码,用namespaces选项把需要用到的命名空间和别名绑定起来,这样后面调用的时候就不用写长长的URL了:
client = Savon.client( wsdl: 'https://someUrl.com/abcd?wsdl', ssl_verify_mode: :none, pretty_print_xml: true, log: true, env_namespace: :soapenv, # 替换成你WSDL里实际的命名空间URL namespaces: { "api01" => "http://your-actual-namespace-url.com/api01", "api02" => "http://another-namespace-url.com/api02" # 如果存在第二个命名空间 } ) do wsse_auth("api_demo_account", "somePassword", :digest) end
第二步:在请求体中指定命名空间
接下来根据你的需求选择合适的方式传递带命名空间的参数:
方式1:给每个元素加上命名空间前缀
如果你的请求里混合了不同命名空间的元素,直接在message的键名前加上对应的别名(比如api01:)就行:
client.call(:operation_name, message: { "api01:api01Req" => [ { "api01:shipCode" => 'ABC', "api01:shipAmount" => 1123, "api02:extraField" => "value" # 属于另一个命名空间的元素 }, # 更多请求项... ] })
方式2:给整个请求指定默认命名空间
如果你的整个请求体都属于同一个命名空间,可以直接在call方法里用namespace参数指定,这样message里的元素就不用加前缀了:
client.call(:operation_name, namespace: "http://your-actual-namespace-url.com/api01", message: { "api01Req" => [ { "shipCode" => 'ABC', "shipAmount" => 1123 }, # 更多请求项... ] } )
方式3:用wrap参数包裹请求
如果你的操作需要把整个请求包裹在某个命名空间的根元素里,可以用wrap参数:
client.call(:operation_name, wrap: "api01:operationRootElement", message: { "api01Req" => [ { "shipCode" => 'ABC', "shipAmount" => 1123 }, # 更多请求项... ] } )
小提示
一定要对照WSDL里的定义来——比如找到<xs:element name="api01Req">对应的targetNamespace属性,确保你的命名空间URL和它完全一致。另外,开启log: true之后,你可以在日志里看到生成的XML,检查命名空间是否正确应用了,方便调试。
内容的提问来源于stack exchange,提问作者jain77
相关产品推荐
相关产品推荐

