WebService是什么
WebService是为了解决不同编程语言之间函数互相调用的方案.好多人都产生过一个这样的疑问,JAVA由于底层源于C++,所以说可以调用C++和C,但是PHP或者Objective-C这样的语言可不可以互相调用?
由于PHP和Objective-C不可能打包成jar包,所以说不可能把一个Objective-C写的.a静态库直接import到Java的工程里,而且Java也读不懂OC的Header文件.有思路的人说我可以自己约定一个协议,或者通过自定义字段的HTTP来传递数据,然后进行解析动态调用,和HTML5与Native的手机App互相调用一样,使用JSON来传递数据.
WebService和这个思路是一样的,只不过不是使用自己定义的协议,而是使用HTTP+XML来互相调用不同语言函数,并且可以放在Web网络上,通过网络互相传递,不需要在本地工程内import的一种方法.
WebService需要做什么准备
既然WebService使用到了HTTP,那么就说明利用了Request和Response的机制,我们来假设两个角色:
- 被调用者A: 把自己的API接口封装成WebService服务,放在公网上,以URL地址的形式
- 调用者B: 调用公开的WebService服务,以Request的形式请求URL
既然是被调用,为了方便调用者查询有哪些接口,需要通过一个机制把这些接口展现给别人,例如C++中.h文件.WebService使用的机制就是WSDL.
而作为调用者,由于是不同语言之间,语法都不一致,不可能直接通过函数调用,需要通过Request请求,带上从WSDL查询到的参数具体值,封装成一个XML的HTTP请求来调用接口.
WebService的具体流程
- 调用者B使用URL后加?WSDL等方式查询WSDL返回报文(XML文件)
- 从WSDL报文里读到函数名和参数列表
- 自己组装SOAP请求,以Request的HTTP报文形式发送
- 得到返回的结果,完成调用
那么这些WSDL和SOAP到底是什么呢?
WSDL(Web Services Discription Language)
WSDL的意思为WebServices描述语言,说白了就是C++的Header文件和Java的文档,其本质是一个网页,当你使用”www.A.com?WSDL"这种网页主域名加"?WSDL"访问,然后会返回一个Response,内容为XML文档.
参考无恙的blog假设这是一个Java的Class
public class Service : System.Web.Services.WebService
{
public Service () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public DateTime HelloWorld(int i)
{
return DateTime.Now;
}
}
那么生成WSDL就是如下
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="HelloWorld">//HelloWorld的入参int类型
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="i" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="HelloWorldResponse">//HelloWorld的返回值dateTime
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="HelloWorldResult" type="s:dateTime" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="HelloWorldSoapIn">
<wsdl:part name="parameters" element="tns:HelloWorld" />//HelloWorld的入参仅有一个
</wsdl:message>
<wsdl:message name="HelloWorldSoapOut">
<wsdl:part name="parameters" element="tns:HelloWorldResponse" />//HelloWorld的返回值,肯定只有一个
</wsdl:message>
<wsdl:portType name="ServiceSoap">
<wsdl:operation name="HelloWorld">//HelloWorld的函数名以及入参和返回值
<wsdl:input message="tns:HelloWorldSoapIn" />
<wsdl:output message="tns:HelloWorldSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="HelloWorld">
<soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ServiceSoap12" type="tns:ServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="HelloWorld">
<soap12:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service">
<wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
<soap:address location="http://localhost:2206/WebSite1/Service.asmx" />
</wsdl:port>
<wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12">
<soap12:address location="http://localhost:2206/WebSite1/Service.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
这些标记中描述的都是什么呢,详细的标签可以通过学习网站进行学习,我看到了一个简易版的描述讲的很好.
<definitions>
<types>
定义 web service 使用的数据类型。为了最大程度的平台中立性,WSDL 使用 XML Schema
语法来定义自己数据类型,而不是采用任何既有的编程语言的数据类型。
</types>
<message>
定义一个操作的数据元素。术语Message让人有点摸不着头脑,
其实就是在定义参数(参数的名字及类型,类型由前面的types节定义)。
</message>
<portType>
WSDL中最重要的元素。也是一个让人摸不着头脑的术语。其实就是定义接口的名称。
接口中的函数使用<operation>元素来声明,函数的名字为operation元素的name属性,
输入参数使用input message声明,输出参数使用output message声明
</operation>
</portType>
<binding>
该部分指定接口与底层实现协议的实现细节。 该节跟编程没有直接的对应关系。
</binding>
<service>
该部分用于指定实现了该接口的一个实例
</service>
</definitions>
SOAP(Simple Object Access Protocol)
SOAP的中文意思是简单对象访问协议“Simple Object Access Protocol”,但是这种缩写已经在标准的1.2版后被废止了.1.2版在2003年6月24日成为W3C的推荐版本.这种缩写容易与SOA——Service-oriented architecture产生歧义,虽然它们之间存在非常大的差异.
其本身是一个Request的HTTP报文,只不过HTTP报文头里多了一个Key值”SOAPAction:”,用来表示这个报文是SOAP请求,而”Content-Type:”也由”text/html” 变成”text/xml”.以下是举例
POST /WebServices/WeatherWebService.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.3603)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://WebXml.com.cn/getSupportCity"
Host: www.webxml.com.cn
Content-Length: 348
Expect: 100-continue
Connection: Keep-Alive
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="http://www.w3schools.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
<soap:Body>
<m:HelloWorld xmlns:m="http://www.w3schools.com/prices">
<m:HelloWorldSoapIn>10</m:HelloWorldSoapIn>
</m:HelloWorld>
</soap:Body>
</soap:Envelope>
其中的soap:Body里面的内容就是请求的内容,请求的方法为HelloWorld,该方法有一个名为HelloWorldSoapIn的参数,参数的值为“10”这个字符串.具体的学习可以参考学习手册.
- Envelope: SOAP的请求内容必须以Envelope做为根节点。
- Header: 这个是可选的,如果需要添加Header元素,那么它必须是Envelope的第一个元素.
- Body: 这个就是请求的主题内容了,用标签表示一个函数,然后用子元素表示它的参数。
在调用中没有指定参数和返回类型,这里不需要指定,因为提供服务的一方自己已经规定好了数据类型,在调用时指定数据类型没有任何意义。
UDDI(Universal Description, Discovery and Integration)
UDDI(Universal Description, Discovery and Integration)可译为”通用描述、发现与集成服务”.是一种目录服务,企业可以使用它对WebServices进行注册和搜索,说白了就是统一管理WebServices.详情可以看学习手册
WebServices的常用用途和新技术
WebServices除了解决不同语言之间的调用,最主要还是为了解决服务器架构中不同模块之间调用,因为不同的模块不在同一块内存中,所以必须有个通讯方式,让他们之间互相都是可用的.WebServices就成了选择.
但是由于WebServices效率实在不高,因为XML本身解析的复杂性,所以说逐渐有了替代技术,比如阿里的DUBBO,或者说RESTful(Representational State Transfer)架构,使用更加轻量级的REST请求来代替SOAP请求,但是它仍是属于WebServices整个框架的一部分,在目前主流的三种Web服务交互方案中REST相比于SOAP以及XML-RPC都更好.