基本原理:
从宏观看,是基于协议(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 ;
}
}
//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());
爱思考的人肯定会问了,这中跨平台之间的调用(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);
更多webservice原理。