Web Service也叫XML Web Service, WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
从表面看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过Web来调用这个应用程序。我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。
WebService三要素SOAP、WSDL、UDDI(UniversalDescriptionDiscovery andIntegration)三者构成了WebService的三要素。下面详细阐述这三大技术:
- SOAP (简易对象访问协议)
- UDDI (通用描述、发现及整合)
- WSDL (Web services 描述语言)
WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议。SOAP提供了标准的RPC(远程调用技术)方法来调用Web Service。
SOAP协议组成:SOAP协议 = HTTP协议 XML数据格式
SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML的,XML是SOAP的数据编码方式。
WSDLWSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数、参数和返回值。它是WebService客户端和服务器端都能理解的标准格式。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应WebService的代理类代码。
UDDIuddi是一个跨产业,跨平台的开放性架构,可以帮助 Web 服务提供商在互联网上发布 Web 服务的信息。UDDI 是一种目录服务,企业可以通过 UDDI 来注册和搜索 Web 服务。简单来说,UDDI 就是一个目录,只不过在这个目录中存放的是一些关于 Web 服务的信息而已。
WebService特性- 跨平台调用
- 跨语言调用
- 远程调用
webservice server端使用spyne库;
安装:pip install spyne
from spyne import Application, rpc, ServiceBase, Iterable, Integer, Unicode
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
class HelloWorldService(ServiceBase):
@rpc(Unicode, Integer, _returns=Iterable(Unicode))
def say_hello(ctx, name: str, times: int):
"""定义方法"""
for i in range(times):
yield u'Hello, %s' % name
@rpc(Unicode, Integer, _returns=Iterable(Unicode))
def say_calc(cxt, data1: int, data2: int):
for i in [" ", "-", "*", "/"]:
yield f"{data1} {i} {data2}= {eval(str(data1) i str(data2))}"
application = Application([HelloWorldService], 'spyne.examples.hello.soap',
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11())
wsgi_application = WsgiApplication(application)
if __name__ == '__main__':
import logging
from wsgiref.simple_server import make_server
logging.basicConfig(level=logging.DEBUG)
logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
logging.info("listening to http://127.0.0.1:8000")
logging.info("wsdl is at: http://localhost:8000/?wsdl")
server = make_server('127.0.0.1', 8000, wsgi_application)
server.serve_forever()
客户端代码
webservice client端使用suds包;
安装: pip install suds
from suds.client import Client
from suds.xsd.doctor import Import, ImportDoctor
url = 'http://localhost:8000/?wsdl'
class WebserviceClient:
def __init__(self, url):
self.imp = Import('http://www.w3.org/2001/XMLSchema',
location='http://www.w3.org/2001/XMLSchema.xsd')
self.imp.filter.add('http://WebXml.com.cn/')
self.doctor = ImportDoctor(self.imp) # 解决解析xml问题
self.client = Client(url)
def get_api(self):
return self.client # 获取webwervice方法和类型
def send_data(self, method, *args, **kwargs):
""" 发送数据"""
try:
cm = eval(f"self.client.service.{method}")
data = cm(*args, **kwargs)
return data
except Exception as e:
print(f"\033[0;30;45m{e}\033[0m")
def get_paratype(self, name):
""" 获取类型参数 """
return self.client.factory.create(name)
if __name__ == '__main__':
cli = WebserviceClient(url=url)
res = cli.get_api()
print(res)
res = cli.send_data("say_hello", "大江东去浪淘尽", 3) # class 'suds.sudsobject.stringArray'
print(f"请求方法: say_hello, 结果类型:{type(res)}, 结果:{res}")
print(f"最终结果: {res[0]}")
res = cli.send_data("say_calc", 10, 2)
print(f"请求方法: say_calc, 结果类型:{type(res)}, 结果:{res}")
print(f"最终结果: {res[0]}")
测试结果
上周部门对接了个兵哥哥家的项目,需求方提供平台,我们的项目作为设备嵌入到他们平台中,双方使用webservice协议进行通信。由于在跟进这个项目,便学习下WebService协议,以及怎么进行数据流转!
吐槽一点,java和python进行加解密数据转换是真的痛苦!
#