注:下文是关于WebService的一个概念和总结,其中的例子来自
http://www.box.net/shared/cyg98xgz78 。 如果您对WebService已经熟悉就不用浪费时间了。
一.什么是Web服务?
Web服务是网络化应用程序的一种,我们可以将Web服务看成一种函数调用,只不过这个函数的实体存在于某个服务器上,而调用在客户端进行。Web服务的思想很简单,即服务器通过网络提供Web服务,其它程序可以将由Web服务器封装的功能无缝的集成到自己的程序中去。Web服务是跨平台跨语言的,它可以由多种语言创建,也可以由多种语言使用。WebService定义了一套标准的调用过程:服务器端使用WSDL来向外界描述它所提供的服务,客户端与服务器端的交互采用SOAP协议。
二.Web服务有什么益处?
处于这个信息化高度发展的世界,每个软件系统都势必要和别的软件系统进行交互,它们可能由不同语言编写运行在不同的服务器上,相互间的调用是一个很大的难题。Web服务就是为解决这些问题而诞生的,它的语言平台无关性可以和任一平台或语言的软件进行交互,这样,Web服务就可以像一座桥梁,可以连通信息化世界中的孤岛。
三.SOAP协议。
在Web服务中,服务器和客户机需要传递接收消息,这就需要对传输的数据格式采取一定的约定措施,这个约定就是SOAP协议,它的全称是简单对象访问协议(Simple Object Access Protocl)。SOAP是基于XML的消息包装器,它既包括客户端送给服务器端希望调用的类和方法的一种消息格式,也包括服务器返回数据的消息格式。有个这个协议,服务器和客户机就能明白对方想干什么。SOAP消息一般基于HTTP来传输,也可以基于其他协议。
下面是一个客户端向服务器发送的SOAP消息例子:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getServerPublicKey xmlns:ns1="http://heyang.com">
</ns1:getServerPublicKey>
</soap:Body>
</soap:Envelope>
客户机向服务器端发送消息时,</soap:Body>中的XML包含要调用的方法和参数,如上述的getServerPublicKey。
下面是服务器反馈给客户机的SOAP消息例子:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getServerPublicKeyResponse xmlns:ns1="hello.XFire"> <ns1:out>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkSpbrSfBIIu+f4mMr7Ie2JdWCBEmlZ1mcoZ0UTNMGaVwexfRax+HC/uusXvkkdoUGYjMaiMycRsQtSOLsfKjOVY/8zBLs0tAOEVelg6MyiF3DV7PVgGEq0dpXJCz0MWFY34a1YJMbPfvPa+VpZaIFbzICUPRhVdBYPAboXthFyQIDAQAB
</ns1:out>
</ns1:getServerPublicKeyResponse>
</soap:Body>
</soap:Envelope>
当服务器端送回消息时,</soap:Body>中包含调用的结果,它可以是单个值,也可以是含有多个值的复杂数据类型。如上面的<ns1:out>中的节点值。
另:在调试WebService程序,想要查看SOAP消息时,可以使用Apache的TCPMon工具,具体使用方法请看
http://www.blogjava.net/heyang/archive/2010/12/10/340294.html.
四.服务器端收到SOAP消息后的动作
以XFire为例,当一个来自客户端的SOPA请求送达WebService服务端时,它会先送到一个Servlet(XFireConfigurableServlet)中(请参看web.xml中的配置),然后开始解析SOAP消息,再根据配置文件services.xml找到接口com.heyang.IService和具体的实现类com.heyang.ServiceImpl中的方法,调用函数产生结果,然后再包装成SOAP消息返回。Axis的做法也是类似的。
五.WSDL
我们现在可以想到Web服务是一个对象,含有一个或多个方法。如何对一个WebService服务器能提供的方法进行说明呢?这里就要用到WSDL(Web Service Description Language),它定义了Web服务提供的可供操作的函数,具体如下:
<?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace="hello.XFire" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:tns="hello.XFire" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
- <wsdl:types>
- <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="hello.XFire">
- <xsd:element name="getServerPublicKey">
<xsd:complexType />
</xsd:element>
- <xsd:element name="getServerPublicKeyResponse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
- <xsd:element name="getResonse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:base64Binary" />
<xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
- <xsd:element name="getResonseResponse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
- <wsdl:message name="getServerPublicKeyRequest">
<wsdl:part name="parameters" element="tns:getServerPublicKey" />
</wsdl:message>
- <wsdl:message name="getResonseResponse">
<wsdl:part name="parameters" element="tns:getResonseResponse" />
</wsdl:message>
- <wsdl:message name="getServerPublicKeyResponse">
<wsdl:part name="parameters" element="tns:getServerPublicKeyResponse" />
</wsdl:message>
- <wsdl:message name="getResonseRequest">
<wsdl:part name="parameters" element="tns:getResonse" />
</wsdl:message>
- <wsdl:portType name="helloPortType">
- <wsdl:operation name="getServerPublicKey">
<wsdl:input name="getServerPublicKeyRequest" message="tns:getServerPublicKeyRequest" />
<wsdl:output name="getServerPublicKeyResponse" message="tns:getServerPublicKeyResponse" />
</wsdl:operation>
- <wsdl:operation name="getResonse">
<wsdl:input name="getResonseRequest" message="tns:getResonseRequest" />
<wsdl:output name="getResonseResponse" message="tns:getResonseResponse" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="helloHttpBinding" type="tns:helloPortType">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="getServerPublicKey">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="getServerPublicKeyRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
- <wsdl:output name="getServerPublicKeyResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
- <wsdl:operation name="getResonse">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="getResonseRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
- <wsdl:output name="getResonseResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="hello">
- <wsdl:port name="helloHttpPort" binding="tns:helloHttpBinding">
<wsdlsoap:address location="http://localhost:8080/XfireSample/services/hello" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
以上内容在浏览器中输入http://localhost:8080/XfireSample/services/hello?wsdl 可以看到。
WSDL本身比较复杂,它主要给程序看的,利用当前大多数的Web服务工具可以生成它,而无需手工编写它。
WSDL的主要目的在于将自己的Web服务的所有相关内容如提供服务的传输方式,服务方法接口,接口参数,服务路径等,生成相应的完全的文档,发布给使用者。使用者可以通过这个WSDL文档,创建相应的SOAP请求消息,通过HTTP传递给Web服务提供者;Web服务提供者在完成请求服务后,将SOAP返回消息传回给请求者,服务请求者再根据WSDL文档将SOAP返回消息解析成程序能够理解的内容。
六.UDDI
UDDI是Universal Description Discovery and Intergretion的缩写,是一种创建注册服务的规范,以便大家将自己的Web Service进行注册发布供使用者查找。
当服务提供者想将自己的Web Service发布,以便外部能找到其服务时,那么服务提供这可以将自己的Web Service注册到相应的UDDI商用注册网站。
UDDI并非一个必须的Web Service组件,服务方完全可以不进行UDDI的注册。因为WSDL文件中已经给出了Web Service的地址URI,外部可以通过它进行相应的Web Service调用.
七.消息服务与WebService的比较
在概念上,Web Service和消息服务它们都是传输数据到别的组件,都是使应用程序之间可以进行异步通信。
消息处理和Web Service是互补的技术,消息服务明确是一项为企业内部而不是为商业领域内的应用程序提供通信的技术,使用消息处理,企业必须与共用的传输格式达成一致,在定义应用程序之间传递的数据方面,消息具有更多的灵活性,另外,Web Service缺乏一个定义好的机制,用于确保SOAP传输和事务处理,这些是消息服务已经定义好和成熟的部分。
Web Service,是松散耦合的组件,应用程序发送请求给它进行处理和数据服务,结果返回给应用程序继续处理,传输机制是Simple Object Access Protocol(简单对象访问协议,SOAP),Web Service通过SOAP能有效的通过HTTP协议发送XML文档。Web Service具有公开性,具有快速推进的标准和大量出版物与技术文档。Web Service有潜力来连接不同的应用程序组件,把软件定义成服务而不是产品。如果应用程序是新建的,则Web Service更为合理。
八.使用Axis的WebService实现。
以上文章是针对XFire的WS实现,如果要用Axis的实现,可以参考这里
http://www.blogjava.net/heyang/archive/2009/10/10/297729.html 或
http://www.blogjava.net/heyang/archive/2009/09/29/296897.html。个人感觉XFire的方案更方便快捷,如果没有限制的话建议使用XFire实现Web Service。
好了,感谢您看到这里。