博客地址:http://blog.csdn.net/a491057947/article/details/22176937
1. 基本原理:
从宏观看,是基于协议( SOAP 协议)的web 服务,从微观层面看,就是一个应用程序,暴露给外界,外界的程序可以通过web的方式来调用其API,我们以前写一个dao或者一个mgr,你要是想调用他的方法,用 java 语言来描述,通常是要通过或者类的实例,然后调用类的方法。比如说:Class UserMgr{
public void checkUser();
},你要是想调用的话,可以通过这样,在你的Action里(假设通过Struts作为客户端程序)
UserMgr um = new UserMgr();
um.checkUser();//注意,这里产生了调用。
那么我们现在只要把这个UserMgr这个类暴露给外界(web Service),让其客户端程序(调用/访问 者-可以是任何程序,只要是它能支持 WebService 就可以),比如说,在c#的程序里要调用一个java应用程序的API(方法),这里是一个Add方法。
package com.zhuweisky.xfireDemo;
public class MathService
{
public int Add(int a ,int b)
{
return a+b ;
}
}
2.
----------------------------------------------------------
//C#
string url = "http://localhost:8080/XFireZhuweiTest/services/MathService" ;
object[] args ={1,2} ;
object result = ESFramework.WebService.WebServiceHelper.InvokeWebService(url ,"Add" ,args) ;
MessageBox.Show(result.ToString());
3.
爱思考的人肯定会问了,这中跨平台之间的调用(WebService)肯定需要一个协议,这里的协议就是与平台无关的RPC-----远程过程调用协议-----它可以真正实现互操作。RPC由三部分组成的。
1.1 XML与XSD
聪明的人一定会想到XML(可扩展的标记语言),它是真正的跨平台的数据格式----平台无关和厂商无关,XML是解决了数据表示问题,但是还缺少了一套标准的数据类型,更没有说怎么样去扩展这套数据类型,例如,整形数到底表示什么?16位,32位,64位,这些对于跨平台来说也是非常重要的,W3C制定的XML Scheme (XSD)就是专门解决这个问题的提出一套标准,它定义了一套标准的数据类型---这个可是任何厂商都要支持的哦,WebService就是使用XSD作为数据类型系统的,当你使用某种类型的语言(. Net or Java)来构建某个WebService,为了符合WebService标准,你所有的数据类型都必须转换位XSD类型。一般来说你用的工具会帮你完整这个标准转换的工作。当然你也可以自己定义。
1.2 SOAP
你建好了一个WebService以后,客户端程序需要去调用,简单对象访问协议(SOAP)提供了标准的RPC方法来调用你的WebService。实际上,SOAP在这里有点用词不当,不一定是对象,你完全可以用C写一个函数作为一个WebService,任然可以通过SOAP进行调用,SOAP规范定义了SOAP消息的格式,以及怎样通过Http协议来使用SOAP。SOAP也是基于XML和XSD的,XML是SOAP的数据编码格式。我猜想一下SOAP的底层的实现原理,以java为例,启动一个 Servlet 程序,这个Servlet接受网络(Http协议)上的SOAP对象------------假设不是WebService的Servlet可能接受的就是普通HttpSerletRequest对象,这个SOAP对象是包含着标准的基于XML的数据。然后这个Servlet最先需要做的事情就是解析这个对象,获得足够多的信息然后调用对应的方法。
1.3 WSDL
你会怎么样向别人介绍你的web Service都有那些功能呢?以及每个函数调用时候的参数呢?你可能写一个文档或者口头告诉需要调用你的WebService的人,这些非正式的方法有一个严重的问题就是,他们的工具(比如 Eclipse 或者Visio Studio)不能提供任何的帮助,因为你的工具根本不了解你的WebService,一个解决的办法是用一个机器能认识的文档,WebService的一个描述语言(WSDL)就是这样一个基于XML的语言,用WebService以及其函数和函数的参数,返回值,因为这是基于xml的,所以WSDL是能够被机器阅读的,人也可以阅读,
4. 用途:
系统集成,系统间的数据交换,分布计算,不同平台的互操作。说白了,就是你可以在.Net上用C#程序调用Java的程序(要求是你的程序是基于WebService的)
5. 实战部分
以java为例,首先特别申明,目前支持WebService的框架有很多(这些框架做了一些基础的工作,使得你编写一个WebService非常地方便,和使用 Hibernate 和JDBC的区别一样),我们这里以集成在 MyEclipse 的xFire框架为例,目前这个框架的发展势头很,对Spring的支持也很充分,类似的支持WebService的框架还有很多,比如说axis。
先用MyEclipse建立一个WebService的工程,然后编写接口和实现类,
public interface IService {
public String testMethod(String testStr);
}
实现类:
public class ECIWebservice implements IService {
public void putMessage(MessageInfo message, String authInfo)
throws UniediException {
// TODO Auto -generated method stub
}
public void putMessages(MessageInfo[] messages, String authInfo)
throws UniediException {
// TODO Auto-generated method stub
}
public MessageInfo getMessage(String appId, String orgCode, String authInfo)
throws UniediException {
// TODO Auto-generated method stub
return null ;
}
public MessageInfo[] getMessages(String appId, String orgCode,
String authInfo, int count) throws UniediException {
// TODO Auto-generated method stub
return null;
}
public String testMethod(String testStr) {
System.out.println("&&&&&&&&&&&&&&&&&Hello: "+testStr+"******************");
return "The para is "+testStr;
}
}
建立一个WebService的工程,其实没有什么什么特别,仅仅是比普通的 Tomcat 工程多WebService.xml文件---这个时候的此文件啥内容都没有。
然后再建立一个WebService,这个时候会提示
默认会把当前所有的webService工程都列出来。选择其中一个,进入一下步:选择你的发布名字,以及要把那个API开放出去(接口和实现类,默认会把所有public的方法都开放出去)。
点击完成。其实做这一步骤仅仅是为了修改webservice.xml文件。
请看修改后的文件内容:
<?xml version="1.0" encoding ="UTF-8"?>
<beans xmlns="http://xfire.codehaus. org /config/1.0">
<service>
<name>testwebservice</name>
<serviceClass>com.webservice. test .IService</serviceClass>
<implementationClass>
com.webservice.test.ECIWebservice
</implementationClass>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
</service></beans>
至此,一个WebService已经建立完成,发布到web容器上(Tomcat和jboss都是可以的)你可以有三种方式来测试。
第一种方式是:
利用MyEclipse自带的Web service explorer。
点击go以后。
点击bindings的link以后,就能看到binding了的所有方法,这些方法都是可以在这里调用的。
我们以一个简单的方法testMethod()作为测试使用。
看看执行后得效果:
第二种方法就是通过,使用浏览器的:
直接在浏览器的地址栏里输入:
http://localhost:8080/mywebservice/services/testwebservice?wsdl
应该可以看到一个XML文件(此文件就是描述文件WSDL)的内容,不过这里只摘写部分内容:
<xsd:element name="testMethod">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
- <xsd:element name="testMethodResponse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
。。。。。
<wsdl:message name="testMethodResponse">
<wsdl:part name="parameters" element="tns:testMethodResponse" />
</wsdl:message>
。。。。。
<wsdl:operation name="testMethod">
<wsdl:input name="testMethodRequest" message="tns:testMethodRequest" />
<wsdl: output name="testMethodResponse" message="tns:testMethodResponse" />
</wsdl:operation>
。。。。
<wsdl:service name="testwebservice">
- <wsdl: port name="testwebserviceHttpPort" binding ="tns:testwebserviceHttpBinding">
<wsdlsoap: address location ="http://localhost:8080/mywebservice/services/testwebservice" />
</wsdl:port>
</wsdl:service>
能看到这部分内容也是说明你的WebService已经好了。
第三种方法就是编写一个客户端程序去测试,特别说明的是,这个客户端可以人适合程序,asp,VB.net, C#, 等
我们是使用了一个java的Application
public static void main(String[] args){
IService is =null;
org.codehaus.xfire.service.Service srvcModel = new ObjectServiceFactory().create(IService.class);
XFireProxyFactory factory = new XFireProxyFactory(XFireFactory.newInstance().getXFire());
String helloWorldURL = "http://localhost:8080/mywebservice/services/testwebservice";
try {
is = (IService)factory.create(srvcModel, helloWorldURL);
is.testMethod("zhangsan");
}catch(Exception ex){
}
}
程序顺利执行,其结果就在tomcat的控制台打印出来了我们想看到的内容了。这里需要特别说明的是,假如不用XFire框架,可是可以编写你自己的WebService的客户端程序的。或者使用了其他的框架(这里以Axis为例):
String endpoint = " http://localhost:8080/mywebservice/services/testwebservice";
Service service = new Service();
Call call = (Call)service.createCall();
call.setTargetEndpointAddress(endpoint);
call.setOperationName(new QName("urn: testwebservice ", "testMethod"));
String resultStr = ((String)call.invoke(new Object[]{theIntArray}));
System.out.println("result_int: " + resultStr);
下面的文章可加深对WSDL的理解。
从标准上来说,整个技术架构是WebServices(带s的), 有时会看到很多人写成WebService(不带s的),其实这是不标准的WebService指的是单独一个服务,而WebServices指的是它的技术架构,目前WebServices技术使用的稍多些,因为它走的是HTTP协议,它可以穿越防火墙,它天生就能穿越80端口,但是WebServices的缺点就是:慢!!因为WebServices是基于HTTP协议传送大文本,实际传送的是XML文件而IIOP(属于CORBA技术架构)协议传送的就是二进制,所以它的效率要比WebServices快,很多所以在一些行业里,也大量的使用了CORBA技术,比如说电信网,而CORBA的缺点就是:编程模型复杂,它是属于重量级的
SOAP——简单对象访问协议
假设我们在本地通过Java写一个main()方法与远程的一个可以是用任何语言写的取得天气预报的服务打交道
如果打交道的过程中采用的是WebServices技术的话,那么它传送给远程的就是XML文件,使用的是SOAP协议
SOAP即简单对象访问协议,其实质就是HTTP+XML,也就是说它是通过HTTP协议来传送XML文件
也就是说SOAP是基于XML的简易协议,可以使应用程序在HTTP之上进行信息交换
或者更简单地说SOAP是用于访问网络服务的协议,而一条SOAP消息就是一个普通的XML文档
使用SOAP协议通信的过程中,远程对象会将所要返回的信息形成一个XML文件传给Stub
然后客户端就会把XML文件转换成Java对象,而当客户端在调用远程服务时
客户端就会把Java对象转换成XML文件作为参数传给Skeleton,而Skeleton就负责把XML文件转换成远程服务的相应语言的对象
比如说服务端是采用Java开发的,那么Skeleton就会将接收到的数据解析成Java对象,再传送给服务端
同理若服务端是采用C#开发的,那么Skeleton就会将接收到的数据解析成C#对象,再传送给服务端
所以,WebServices能够实现异构语言的通信,可以用来整合异构系统
同理,如果不是异构系统的话,也就没有必要使用WebServices技术
比如说客户端和远程对象都是采用Java开发的,那么就没有必要使用WebServices了
因为二者都是采用Java开发的,它们之间可以直接以二进制来传输数据,访问效率会快的很多
而WebServices其实就是基于XML的数据交换,即WebServices所传送的是大文本,效率自然就慢了
除非我们的系统是采用多语言开发的,那么就可以考虑使用WebServices技术
或者说我们的系统想做的通用一些,则可以采用并开放WebServices的一些方法
其实SOAP就是用来最终完成Web服务的调用的,而WSDL则用于描述如何使用SOAP来调用Web服务
WSDL——WebServices描述语言
仍以上面为例,即客户端采用Java开发,服务端是采用C#开发的天气预报的服务
作为客户端,它知道在服务端提供了一个能够获取天气预报的服务,并且客户端也可以调用该服务
但作为服务端,应该对这些服务进行描述,以告诉客户端都有哪些服务可供调用
而这个服务是不能用C#语言来描述的,因为采用Java开发的客户端是无法识别的
所以服务端就需要使用一套语言来描述它所提供的服务,这套语言就是WSDL
其实WSDL就是一个XML文件,也就是说WebServices定义了一套标准,里面都是XML格式
使用这套标准来描述服务端对外提供的服务,比如C#的方法名、参数名、返回值等信息
假设服务端的天气预报功能还没有使用C#来实现,并且客户端也没有使用Java来实现
这时突然要求定义一套标准来描述一下即将准备实现的服务端的天气预报的功能
并且客户端可以任意调用这个天气预报功能,此时就可以写一套WSDL来描述方法名、参数、返回值等信息
当服务端的C#得到该WSDL时,就可以通过WSDL生成C#代码,然后它就可以把取得天气预报功能的逻辑补充上
而客户端的Java在得到这个WSDL之后,同样可以生成Java代码,然后把相应的约定的接口实现补充上
在使用WSDL生成相应语言的代码的过程中,就需要用到一些引擎来实现
比如在WebServices中就有:Axis、CXF、XFire等框架,它们就可以根据WSDL解析成Java代码
所以WSDL是一种中立的语言
而CORBA架构中也有类似于WSDL的一种东西,叫做IDL,它的语法类似于C++语言,但IDL不是C++
UDDI——发现和整合服务
类似于JNDI。客户端去寻找服务端所能提供的服务时,可以找UDDI索要,而UDDI就会把WSDL传送给客户端
实际上,该过程一般不通过UDDI,而是直接把WSDL拷贝过来就可以了,可以通过Email或硬盘直接拷贝
当客户端得到WSDL之后,就可以通过SOAP协议与远程的服务端进行通信了