基本原理:
從巨集觀看,是基於協議(SOAP協議)的web 服務,從微觀層面看,就是一個應用程序,暴露給外界,外界的程序可以通過web的方式來調用其API,我們以前寫一個dao或一個mgr,你要是想呼叫他的方法,用java語言來描述,通常是要通過或類別的實例,然後呼叫類別的方法。比如說:
Class UserMgr{
public void checkUser();
},你要是想調用的話,可以透過這樣,在你的Action裡(假設透過Struts作為客戶程式)
;
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原理相关文章请关注PHP中文网!