webservice概念

1. Web service是一个平台独立的,松耦合的,自包含的、基于可编程的web的应用程序

2. 使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序

SOAP :简单对象访问协议Simple Object Access Protocol,传输层,XML传输消息
WSDL:Web Server Description Language :Web Server描述语言(元数据),给客户端生成代理类的一个描述信息
UDDI :提供了一组基于标准的规范用于描述和发现服务,统一描述,发现和集成(UDDI-Universal Descript,Discovery,Integration),提供注册和查找服务 客户端在UDDI注册表(Registry)查找服务,取得服务的WSDL描述,通过SOAP调用服务。

简单的来说,webservice就是一个建立在Http之上数据结构为XML的协议,其中并不像平常访问API那样去访问web service接口,而是要访问相对应XML中的方法,以实现远程跨平台、跨语言的方法调用。通过XML形式说明服务在什么地方,以XML形式说明服务提供什么样的方法

一般来说内部开发会使用这种模式,但是也不缺乏对外公开的服务 如:手机号地区查询、天气预报查询 …

python对接web service

那么,如何使用python对接web service呢,我们可以使用suds!

pip3 install suds

为了方便测试客户端,可以使用这个网址中的web服务:http://www.webxml.com.cn/zh_cn/index.aspx

suds 的目标是基于 soap 的 Web 服务提供类似 RPC 的接口。这意味着在大多数情况下,用户不需要关心 WSDL 和引用模式的复杂性。无论指定哪种 soap 消息样式,服务方法的签名都保持不变。确实检查 WSDL 的用户会注意到,即使使用文档 soap 消息样式,每个方法的签名也类似于 RPC。

主要接口为 Client对象。它提供了配置库和定义的子命名空间的方法。创建 Client,它会处理 WSDL和引用的模式。从该信息中,它导出该信息的表示,该表示用于向用户提供服务描述和消息/回复处理

在调试中,可以使用logging来记录日志

import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
  • suds.client: 在此模块上将日志记录级别设置为 DEBUG 以查看 soap 消息(输入和输出)和 http 标头。
  • suds.transport: 在此模块上将日志记录级别设置为 DEBUG 以查看有关 soap 消息(输入和输出)和 http 标头的更多详细信息。
  • suds.xsd.schema: 在此模块上将日志记录级别设置为 DEBUG 以查看模式的消化。
  • DEBUGsuds.wsdl: 在此模块上将日志记录级别设置为以查看消化 WSDL。

suds.Client为使用 Web 服务提供了统一的 API。该对象包含2个子命名空间:

service : service命名空间为消费的服务提供代理。该对象用于调用服务端点提供的操作(方法)。

factory : factory命名空间提供了一个工厂,可用于创建 WSDL 中定义的对象和类型的实例。

这两个为每个服务的 WSDL 的 url 创建一个客户端

from suds.client import Client
url = 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl'
client = Client(url)
print(client.__str__())'''
Suds ( https://fedorahosted.org/suds/ )  version: 1.1.2Service ( WeatherWS ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREF'''# 示例出现了 服务名为 WeatherWS 的6个方法以及91个Types, 例如 getRegionCountry()、getRegionDataset() ...

如果出现 suds.TypeNotFound: Type not found: ‘(schema, http://www.w3.org/2001/XMLSchema, )’ 这种错误,就进一步处理

from suds.client import Client
from suds.xsd.doctor import ImportDoctor, Importurl = 'http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl'
imp = Import('http://www.w3.org/2001/XMLSchema',location='http://www.w3.org/2001/XMLSchema.xsd'
)
imp.filter.add('http://WebXml.com.cn/')
doctor = ImportDoctor(imp)
client = Client(url, doctor=doctor)

简单参数的调用

上面代码中返回WSDL中可调用的方法,现在就试着调用 getSupportCityDataset(xs:string theRegionCode)

可以看到方法中有参数并且为str类型,需要填入查询的地区代码。如果没有参数则直接调用

client = Client(url, doctor=doctor)
result = client.service.getSupportCityDataset("北京") # 也可以填写地区名称
print(result.diffgram.Region.City) # 获取到支持的城市数据级'''
[(City){_id = "City1"_rowOrder = "0"CityID = "792"CityName = "北京"}, (City){_id = "City2"_rowOrder = "1"CityID = "785"CityName = "昌平"}, (City){_id = "City3"_rowOrder = "2"CityID = "826"CityName = "大兴"}...]
'''

复杂参数

还有一些比较复杂的参数
比如 addPerson()方法接受一个类型为Person的参数,并具有一个签名:addPerson(Person person),其中参数类型后面跟着它的名称,相应的类型能在返回的Types中找到。在getWeather()的情况下,参数是xs:string类型的字符串 和 xs:int类型的整数。

因此,要创建一个Person对象作为参数传递,我们需要使用工厂子命名空间获得一个Person参数,如下所示:

person = client.factory.create('Person')
print(person)'''
(Person)={phone = []age = NONEname(Name) ={last = NONEfirst = NONE}}'''
# 对象是按照 WSDL 定义创建的。phone列表是空的,所以必须创建一个`Phone` 对象:
phone = client.factory.create('Phone')
phone.npa = 111
phone.nxx = 222
phone.number = 123123# 创建一个`Name` 对象
name = client.factory.create('Name')
name.first = 'lu'
name.last = 'wei'# 设置person属性
person.name = name
person.age = 25
person.phone = [phone]# 或者
person.phone.append(phone)# 调用方法
try:person_added = client.service.addPerson(person)
except WebFault as e:print e

或者可以使用Dict形式组装复杂参数

person = {}phone = {'npa':111,'nxx':222,'number':123123,
}name = {'first':'lu','last':'wei'
}person['name'] = name
person['age'] = 25
person['phone'] = [phone,]try:person_added = client.service.addPerson(person)
except WebFault as e:print e

客户端可以配置为将web故障作为WebFault抛出,或者返回元组(<status>,<return value>),如下所示:

client = client(url, faults=False)
result = client.service.addPerson(person)
print(result)

suds的client选项说明

suds客户端有许多可以用来控制库的行为的功能。有些是通用选项,有些是运输选项。尽管选项对象是公开的,但首选和支持的设置/取消设置选项的方式是通过:

  • Client 构造函数
  • Client.set_options()
  • 构造函数 Transport

一般选项:

faults: 控制web故障行为

service: 控制多服务wsdl的默认服务名称

port:控制多端口服务的默认服务端口

location: 这将覆盖WSDL中定义的服务端口地址URL

transport: 控制插件web传输

cache: 提供与加载WSDL相关的文档和对象的缓存。肥皂信封从不缓存

cachingpolicy: 缓存策略,决定如何缓存数据。默认值为0。版本0.4+

​ 0=WSDL和XSD等XML文档

​ 1=WSDL对象图

soap标头:提供soap标头

wsse: 提供WS-Security对象

__inject:控制消息/回复消息的注入

doctor: 架构doctor指定用于修复损坏的架构的对象

xstq: XML架构类型限定标志指示xsi:type属性值应该由命名空间限定

prefixs: soap消息的元素应该使用XML前缀进行限定(在需要时),而不是xmlns=“”语法

retxml: 导致返回I{raw}soap信封而不是python对象图的标志

autoblend:确保WSDL中定义的架构相互导入的标志

nosend: 导致suds生成soap信封但不发送它的标志。相反,返回RequestContext Default:False

sortnamespaces: 使sud在存储命名空间时按字母顺序对其进行排序的标志。默认值:True

allowUnknownMessageParts: 与操作的WSDL架构定义相比,在接收web服务回复时检测到未知消息部分时引发异常。默认值:False

只有在使用默认传输时,才会使用传递给客户端构造函数的传输选项,如下所示:

proxy: 控制http代理设置。

timeout: URL连接超时(秒)默认值=90。每个方法调用也可以设置超时

headers: 提供额外的http标头

username: HTTP身份验证的用户名

password:HTTP身份验证的密码

通过交换零部件实现自定义行为

通过交换自定义,可以自定义suds的各种行为方式

初始化带有列表的可选阵列

在一些未发布的suds-jurko版本中,所有children元素都填充了空列表。这在suds社区中被修复为一种回归。这可能是所需的行为,因为它简化了构造复杂的请求。要获得先前的行为,请使用自定义生成器类,例如:

from suds.client import Client, Builderclass AlwaysInitializeBuilder(Builder):def skip_value(self, type):return Falseclient = Client(url)
client.factory.builder = AlwaysInitializeBuilder(client.factory.builder.resolver)

获取枚举变量

假设 wsdl 定义了以下枚举:

<xs:simpleType name="resourceCategory"><xs:restriction base="xs:string"><xs:enumeration value="PLATFORM"/><xs:enumeration value="SERVER"/><xs:enumeration value="SERVICE"/></xs:restriction>
</xs:simpleType>

实力化枚举变量

resourceCategory = client.factory.create('resourceCategory')
client.service.getResourceByCategory(resourceCategory.PLATFORM)

工厂Factory

工厂用于创建由wsdl/schema定义的复杂对象

使用create()方法,因为它返回的对象已经具有正确的结构和模式类型信息。由于xsd支持嵌套类型定义,所以使用(.)点表示法的create()也是如此。例如,假设(Name)类型没有定义为顶级的“命名”类型,而是在(Person)类型中定义的。在这种情况下,创建(Name)对象必须通过其父对象的名称进行量化,并使用如下点表示法:

name = client.factory.create('Person.Name')

如果类型与wsdl(targetNamespace)在同一个命名空间中,则可以在没有任何命名空间限定的情况下引用它。如果不是,则该类型必须由命名空间前缀限定,例如:

name = client.factory.create('ns0:Person')

或者,名称可以由命名空间本身使用完整限定语法:

name = client.factory.create('{http://test.server.enterprise.rhq.org/}person')

当使用 (.) 点符号指定路径时,限定名称只能用于名称的第一部分

多个服务和多个端口的 WSDL

如果WSDL 定义了多个服务多个端口

Suds ( https://fedorahosted.org/suds/ )  version: 1.1.2Service ( WeatherWS ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS(WeatherWSSoap12)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFSService ( WeatherWSTwo ) tns="http://WebXml.com.cn/"Prefixes (1)ns0 = "http://WebXml2.com.cn/"Ports (2):(WeatherWSSoap)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS(WeatherWSSoap12)Methods (6):getRegionCountry()getRegionDataset()getRegionProvince()getSupportCityDataset(xs:string theRegionCode)getSupportCityString(xs:string theRegionCode)getWeather(xs:string theCityCode, xs:string theUserID)Types (91):ArrayOfStringxs:ENTITIESxs:ENTITYxs:IDxs:IDREFxs:IDREFS

想要指定服务或者指定端口如下所示

# 例子 client.service[service][port].getRegionCountry()client.set_options(service='WeatherWSTwo', port='WeatherWSSoap12')
client.service.getRegionCountry()# 或者
client.service['WeatherWSTwo']['WeatherWSSoap12'].getRegionCountry()# 或者按下标
client.service[1][0].getRegionCountry()# 只选择service
client.service['WeatherWSTwo'].getRegionCountry()# 按照service下标
client.service[1].getRegionCountry()# 只按照port
client.set_options(port='WeatherWSSoap')

请注意,如果WSDL定义了多个服务,则必须通过选项或使用下标语法来限定服务,以便指定端口

suds对接web service相关推荐

  1. 万物皆可集成系列:低代码对接Web Service接口

    我们知道活字格支持不写代码实现双向API绑定,那么没那么主流的Web Service接口(SOAP协议+XML交互格式)呢?其实对接的思路没有那么复杂,得用C#编码来对接的. 作为一款企业级低代码开发 ...

  2. 【分布计算环境学习笔记】9 Web Service

    作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.概述: 在现有的各种异构平台的基础上,构筑一个通用的,与应用无关.语言无关的技术层,各种不同平台之上的应用依 ...

  3. python接口测试实战_Python接口测试实战5(下) - RESTful、Web Service及Mock Server

    课程目录 更多学习资料请加添加作者微信:superz-han获取 本节内容 REST及RESTful API Web Service XML解析 Mock Server REST及RESTful AP ...

  4. 用cxf公布和调用web service

    用cxf发布和调用web service 最近我们的系统需要和一个第三方系统对接,对接的方式是通过web service,所以就学习了一下这方面的东西 用CXF来做web service是比较简单的, ...

  5. 使用WSE实现Web Service安全

    WSE(Web Services Enhancements)是微软为了使开发者通过.NET创建出更强大,更好用的Web Services而推出功能增强插件.现在最新的版本是WSE2.0(SP2).本文 ...

  6. 关于php调用.net的web service 踩过的坑

    从前一阵开始,公司要和对方做web service对接.由于对方使用.net语言,而我方使用php.本来经理是要求我们也用.net写web service的服务端.而我上学时学的.net全忘了... ...

  7. Java RESTful Web Service实战(第2版)

    Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著 图书在版编目(CIP)数据 Java RESTful Web Service实战 / 韩陆著. -2版 ...

  8. 如何区别API、REST API、RESTful API和Web Service之间的异同

    当你看到API接口你会想起什么?是接口.第三方调用.还是API文档?初看你可能会觉得这太熟悉了,这不是系统开发日常系列吗?但你仔细想一想,你会发现API的概念在你脑海里是如此的模糊.如何你通过搜索引擎 ...

  9. Web Service Case Study: 认证考试申请服务

    本文是Web Service Case Study系列文章的第二篇.在这篇文章中,我将围绕一个认证考试申请系统展开设计和讨论,这个应用与本文的系统不同,主要是面向B2C模式的应用,着眼点在于如何将这个 ...

最新文章

  1. 【OpenCV 4开发详解】分割图像——Grabcut图像分割
  2. 58 Node.js中操作mongoDB数据库
  3. win10下安装TensorFlow(CPU only)
  4. Vmware虚拟机安装Ubuntu 16.04 LTS(长期支持)版本+VMware tools安装
  5. 核心期刊 CA JST CSCD 含金量_期刊评介|《仪表技术与传感器》科技期刊的阿玛尼,只管投就对了!...
  6. 【网络流24题----09】方格取数问题
  7. Linux系统编程30:进程信号之产生信号的四种方式(Core Dump,kill,raise)
  8. Bootstrap3 排版之水平对齐
  9. python学到哪知道baseline_Python NLTK学习6(创建词性标注器)
  10. 使用C#操作Oracle Spatial的SDO_GEOMETRY对像(读取和写入)
  11. 第四次博客:循环单链表解决约瑟夫环问题
  12. Asciidoctor Maven插件使用
  13. 线性规划中的单纯形法与内点法(原理、步骤以及matlab实现)(二)
  14. 编程软件下载地址(java/vs/python、pycharm/Web/eclipse)
  15. zabbix监控服务器raid状态,基于Zabbix的MegaRAID阵列卡状态监控
  16. qqpcmgr_docpro 这个隐藏文件无法删除的问题解决方法
  17. pyhon身份证验证
  18. Word 2003 出现 向程序发送命令时出现问题 的 解决方案
  19. python跳出双循环break图例
  20. Linux查看本机端口开启,Linux 实用指令之查看端口开启情况

热门文章

  1. 用聊天机器人假扮人类
  2. java 使用poi生成excel
  3. java中localhost是怎么回事?干什么用的?
  4. 飞行员兄弟 JAVA题解
  5. MySQL主从同步的原理
  6. Activity到底是什么(新手学Android)
  7. ThreadLocal不好用?那是你没用对!
  8. 猜数字游戏项目验收总结
  9. 人工智能前景和现状如何?AI发展趋势分析
  10. Java中将String转成Long或long