在运行时更改suds客户端的web服务URL(保持wsdl不变)

8 投票
3 回答
10293 浏览
提问于 2025-04-15 22:43

首先,我的问题和这个问题有点相似。

但其实有点不同。我们有一系列的环境,里面有一套相同的服务。对于某些环境(本地的那些),我们可以访问到wsdl文件,因此可以生成suds客户端。可是对于外部环境,我们无法访问wsdl。不过因为它们是一样的,我希望能只改一下网址,而不需要重新生成客户端。我尝试过克隆客户端,但没成功。


编辑:添加代码:

    host='http://.../MyService.svc'
    wsdl_file = 'file://..../wsdl/MyService.wsdl'

    client = suds.client.Client(wsdl_file, location=host, cache=None)

    #client = baseclient.clone()

    #client.options.location = otherhost

    client.set_options(port='BasicHttpBinding_IMyService')

    result = client.service.IsHealthy()

这段代码给我抛出了这个异常:

消息的动作 'http://tempuri.org/IMyService/IsHealthy' 在接收方无法处理,因为在EndpointDispatcher处出现了合同过滤器不匹配。这可能是因为合同不匹配(发送方和接收方的动作不一致)或者发送方和接收方之间的绑定/安全性不匹配。请检查发送方和接收方是否有相同的合同和相同的绑定(包括安全要求,例如消息、传输、无)。

问题是,如果我直接把客户端设置为主机,它就能正常工作:

client = suds.client.Client(host)

如你所见,我尝试过克隆客户端,但还是出现了同样的异常。我甚至试过这个:

    baseclient = suds.client.Client(host)

    client = baseclient.clone()

    client.options.location = otherhost
    ....

结果还是得到了同样的异常。

有人能帮我吗?

3 个回答

1

你可以通过指定服务的 location 来实现这个功能。假设你有一个叫 clientClient 对象,你可以通过更新 client.options.location 中的 URL 来修改服务的位置。

另外,你还可以使用本地的 WSDL 文件作为构建客户端时的 url,只需在 URL 前加上 file:// 的格式,比如 file:///path/to/service.wsdl。这也是一个可行的选择。当然,你还需要指定 location,这样才能覆盖 WSDL 中的默认位置。

3

我搞定了!
我也不知道我是怎么弄明白的,不过经过一些猜测和一点运气,我终于得到了这个:

    wsdl_file = 'file://...../MyService.wsdl'

    client = suds.client.Client(wsdl_file)
    client.wsdl.url = host #this line did the trick

    client.set_options(port='BasicHttpBinding_IMyService')

    result = client.service.IsHealthy()

而且它真的能用!
我找不到关于这个属性(client.wsdl.url)的任何文档,但它确实有效,所以我把它发出来,以防有人遇到同样的问题。

6
client.sd[0].service.setlocation(new_url)

...这是一种“手动”的方法,也就是说,根据服务描述来操作。

client.set_option(new_url)

...也应该可以用,根据作者的说法

options 是一个被包装/保护的属性 -- 直接修改可能会被忽略。

撰写回答