【轉】Web Service實踐之——開始XFire

源文章頁是轉載的,那麼再轉載此?http://www.cnblogs.com/niuxiaohao/archive/2010/10/27/1862478.html

一、Axis與XFire的比較
XFire是與Axis2 並列的新一代WebService平臺。之所以並稱爲新一代,因爲它:
1、支持一系列Web Service的新標準--JSR181、WSDL2.0 、JAXB2、WS-Security等;
2、使用Stax解釋XML,性能有了質的提高。XFire採用Woodstox 作Stax實現;
3、容易上手,可以方便快速地從pojo發佈服務; 
4、Spring的結合;
5、靈活的Binding機制,包括默認的Acegis,xmlbeans,jaxb2,castor。
 
XFire與Axis1性能的比較
1、XFire比Axis1.3快2-6倍
2、XFire的響應時間是Axis1.3的1/2到1/5
 
XFire與Axis2的比較
雖然XFire與Axis2都是新一代的WebService平臺,但是Axis2的開發者太急於推出1.0版本,所以1.0還不是一個穩定的版本,它的開發者宣稱1.1版本即將推出,希望1.1版本會是個穩定的版本。在XFire捐獻給apache後有人認爲Axis2將會滅亡。其實在很多人眼裏,Axis2並不是pojo形式,現在也好象XFire比Axis更有市場,也有很多人開始從Axis轉向XFire。
據說,XFire確實比Axis2簡單很多

AXIS VS CXF
在SOA領域,我們認爲Web Service是SOA體系的構建單元(building block)。對於作過WebService的開發人員來說,AXIS和CXF一定都不會陌生。這兩個產品都是Apache孵化器下面的Web Service開源開發工具。 Axis2的最新版本是1.3,CXF現在已經到了2.0版本。

這兩個框架 都是從已有的開源項目發展起來的。Axis2是從Axis1.x系列發展而來。CXF則是XFire和Celtix項目的結合產品。Axis2是從底層全部重新實現,使用了新的擴展性更好模塊架構。 CXF也重新的深化了XFire和Celtix這兩個開發工具。

新產品的退出導致了幾個問題。是不是現有的使用Axis 1.x,XFire和Celix的應用需要遷移的新的版本上。如果一個開發人員確定要遷移它的應用到新的框架上,那麼他應該選擇哪一個呢?相反的,如果一個開發者決定從頭開發一個新的Web Service,他應該使用哪個呢? 這兩個框架哪一個更好一些呢?

對於系統遷移來說,也許遷移到新的框架並不難。Axis和CXF都提供了遷移的指導。能夠給開發者一些遷移的技巧和經驗。但是對於這樣遷移,這兩個開源項目都沒有提供遷移的工具。對於這樣的遷移工作,儘管很值得去尋找所有的可行方案。Axis2和CXF都有各自不同的WebService開發方法,每個方法都有相當數量擁護者。

通過一個比較矩陣來比較Axis2和CXF變得有現實的意義。這兩個項目都開發不夠成熟,但是最主要的區別在以下幾個方面:
1. CXF支持 WS-Addressing,WS-Policy, WS-RM, WS-Security和WS-I Basic Profile。Axis2不支持WS-Policy,但是承諾在下面的版本支持。
2. CXF可以很好支持Spring。Axis2不能
3. AXIS2支持更廣泛的數據並對,如XMLBeans,JiBX,JaxMe和JaxBRI和它自定義的數據綁定ADB。注意JaxME和JaxBRI都還是試驗性的。CXF只支持JAXB和Aegis。在CXF2.1
4. Axis2支持多語言-除了Java,他還支持C/C++版本。

比較這兩個框架的Web Service開發方法與比較它們的特性同樣重要。 從開發者的角度,兩個框架的特性相當的不同。 Axis2的開發方式類似一個小型的應用服務器,Axis2的開發包要以WAR的形式部署到Servlet容器中,比如Tomcat,通過這些容器可以對工作中的Web Service進行很好的監控和管理。Axis2 的Web administrion模塊可以讓我們動態的配置Axis2.一個新的服務可以上載,激活,使之失效,修改web服務的參數。管理UI也可以管理一個或者多個處於運行狀態的服務。這種界面化管理方式的一個弊端是所有在運行時修改的參數沒有辦法保存,因爲在重啓動之後,你所做的修改就會全部失效。

Axis2允許自己作爲獨立的應用來發布Web Service,並提供了大量的功能和一個很好的模型,這個模型可以通過它本身的架構(modular architecture)不斷添加新的功能。有些開發人員認爲這種方式對於他們的需求太過於繁瑣。這些開發人員會更喜歡CXF。

CXF更注重開發人員的工效(ergonomics)和嵌入能力(embeddability)。大多數配置都可以API來完成,替代了比較繁瑣的XML配置文件, Spring的集成性經常的被提及,CXF支持Spring2.0和CXF's API和Spring的配置文件可以非常好的對應。CXF強調代碼優先的設計方式(code-first design),使用了簡單的API使得從現有的應用開發服務變得方便。

不過你選擇Axis2還是CXF,你都可以從開源社區得到大量的幫助。這兩個框架都有商業公司提供服務,WSO2提供AXIS2的支持,Iona提供CXF的支持。這兩公司都有很活躍的開發者社區。 Axis2出現的時間較早,CXF的追趕速度快。我的建議是:如果你需要多語言的支持,你應該選擇AXIS2。如果你需要把你的實現側重JAVA並希望和Spring集成,CXF就是更好的選擇,特別是把你的Web Service嵌入其他的程序中。如果你覺得這兩個框架的新特性對於你並沒有太大的用處,你會覺得Axis1也是不錯的選擇,你應該繼續使用它知道你有充分的理由去更換它。


二、開始XFire的生火之旅:
1、配置XFire運行環境:
在Tomcat下新建一個Web Applications,命名爲stove,然後在其WEB-INF目錄下新建一個web.xml文件,文件中輸入:

Xml代碼 
  1. <?xml version="1.0" encoding="GB2312">  
  2. <!DOCTYPE web-app  
  3.     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  4.     "http://java.sun.com/dtd/web-app_2_3.dtd">  
  5.       
  6. <web-app>  
  7.   
  8.   <servlet>  
  9.     <servlet-name>XFireServlet</servlet-name>  
  10.     <display-name>XFire Servlet</display-name>  
  11.     <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>  
  12.   </servlet>  
  13.   
  14.   <servlet-mapping>  
  15.     <servlet-name>XFireServlet</servlet-name>  
  16.     <url-pattern>/servlet/XFireServlet/*</url-pattern>  
  17.   </servlet-mapping>  
  18.   
  19.   <servlet-mapping>  
  20.     <servlet-name>XFireServlet</servlet-name>  
  21.     <url-pattern>/services/*</url-pattern>  
  22.   </servlet-mapping>  
  23.   
  24. </web-app>  

其中主要就是引入了XFireServlet,用以處理Web Service請求,並且負責提供Web Service的WSDL,如果你發佈了一個名爲BookService的WebService,則可以通過網址:
http://<服務器>[:端口]/<webapp名>/services/BookService
來訪問這個WebService,並且通過地址:
http://<服務器>[:端口]/<webapp名>/services/BookService?WSDL  來得到這個WebService的WSDL信息。

2、開發最簡單的WebService
在WEB-INF目錄下新建src文件夾,然後再建一個package:
cn.com.pansky.webservice.xfire.study
,在這個包下面新建一個接口:

Java代碼 
  1. package cn.com.pansky.webservice.xfire.study;  
  2.   
  3. public interface SayHiService{  
  4.   public String sayHi(String name);  
  5. }  

這個接口是告訴服務器你的WebService哪些方法可以被用戶調用的。下面我們再來寫一個SayHiService的實現類,以完成業務邏輯:

Java代碼 
  1. package cn.com.pansky.webservice.xfire.study;  
  2.   
  3. public class SayHiServiceImpl implements SayHiService{  
  4.   public String sayHi(String name){  
  5.     if(name==null){  
  6.       return "連名字也不肯告訴我嗎?";  
  7.     }  
  8.     return name+", 你吃了嗎?沒吃回家吃去吧。";  
  9.   }  
  10.   
  11.   public String 不告訴你(){  
  12.     return "我的名字不告訴你!";  
  13.   }  
  14. }  

 這個類實現了sayHi方法,該方法是可以通過WebService調用訪問到的。另外還實現了一個方法“不告訴你”,該方法因爲沒有在接口SayHiService中定義,所以不能被WebService調用到。
   這個例子足夠簡單吧,就跟我們剛學Java時寫的"Hello world"沒什麼兩樣。
到這裏爲止,我們做的跟平時的Java開發沒啥區別,該如何來發布WebService呢?

3、把JAVA類發佈爲WebService:
在WEB-INF/classes目錄下新建文件夾:META-INF/xfire,然後在該文件夾下新建一個XML文件:services.xml,文件內容如下:

Xml代碼 
  1. <beans xmlns="http://xfire.codehaus.org/config/1.0">  
  2.   <service>  
  3.     <name>SayHiService</name>  
  4.     <namespace>http://cn.com.pansky/SayHiService</namespace>  
  5.     <serviceClass>cn.com.pansky.webservice.xfire.study.SayHiService</serviceClass>  
  6.     <implementationClass>cn.com.pansky.webservice.xfire.study.SayHiServiceImpl</implementationClass>  
  7.   </service>  
  8. </beans>  

 這個文件定義一個WebService: SayHiService,並同時定義了接口和實現類。
好了,該建的文件基本建完了,現在想辦法把src下的java文件編譯成class,並複製到WEB-INF/classes目錄下

4、啓動Tomcat,測試WebService
如果Tomcat還沒配置好,抽兩分鐘再配一下。再把Tomcat啓動起來。
再打開瀏覽器,輸入:
http://localhost/stove/services
,服務器返回的結果如下:
Available Services:
    * SayHiService [wsdl]
     Generated by XFire ( http://xfire.codehaus.org ) 
我們看到我們的WebService已經佈署成功了,我們再看看它的WSDL信息:

Xml代碼 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <wsdl:definitions targetNamespace="http://cn.com.pansky/SayHiService" xmlns:tns="http://cn.com.pansky/SayHiService" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">  
  3.   <wsdl:types>  
  4. <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://cn.com.pansky/SayHiService">  
  5. <xsd:element name="sayHi">  
  6. <xsd:complexType>  
  7. <xsd:sequence>  
  8. <xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string"/>  
  9. </xsd:sequence>  
  10. </xsd:complexType>  
  11. </xsd:element>  
  12. <xsd:element name="sayHiResponse">  
  13. <xsd:complexType>  
  14. <xsd:sequence>  
  15. <xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string"/>  
  16. </xsd:sequence>  
  17. </xsd:complexType>  
  18. </xsd:element>  
  19. </xsd:schema>  
  20.   </wsdl:types>  
  21.   <wsdl:message name="sayHiRequest">  
  22.     <wsdl:part name="parameters" element="tns:sayHi">  
  23.     </wsdl:part>  
  24.   </wsdl:message>  
  25.   <wsdl:message name="sayHiResponse">  
  26.     <wsdl:part name="parameters" element="tns:sayHiResponse">  
  27.     </wsdl:part>  
  28.   </wsdl:message>  
  29.   <wsdl:portType name="SayHiServicePortType">  
  30.     <wsdl:operation name="sayHi">  
  31.       <wsdl:input name="sayHiRequest" message="tns:sayHiRequest">  
  32.     </wsdl:input>  
  33.       <wsdl:output name="sayHiResponse" message="tns:sayHiResponse">  
  34.     </wsdl:output>  
  35.     </wsdl:operation>  
  36.   </wsdl:portType>  
  37.   <wsdl:binding name="SayHiServiceHttpBinding" type="tns:SayHiServicePortType">  
  38.     <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>  
  39.     <wsdl:operation name="sayHi">  
  40.       <wsdlsoap:operation soapAction=""/>  
  41.       <wsdl:input name="sayHiRequest">  
  42.         <wsdlsoap:body use="literal"/>  
  43.       </wsdl:input>  
  44.       <wsdl:output name="sayHiResponse">  
  45.         <wsdlsoap:body use="literal"/>  
  46.       </wsdl:output>  
  47.     </wsdl:operation>  
  48.   </wsdl:binding>  
  49.   <wsdl:service name="SayHiService">  
  50.     <wsdl:port name="SayHiServiceHttpPort" binding="tns:SayHiServiceHttpBinding">  
  51.       <wsdlsoap:address location="http://localhost/stove/services/SayHiService"/>  
  52.     </wsdl:port>  
  53.   </wsdl:service>  
  54. </wsdl:definitions>  

 這個文件跟我們用Axis生成的基本是一樣的。

5、享受美味的時刻
WebService這道大餐算是烹製好了,現在是享用美餐的時候了。
我們寫一個客戶端吃掉這道大餐:

Java代碼 
  1. package cn.com.pansky.webservice.xfire.study;  
  2.   
  3. import java.net.MalformedURLException;  
  4. import java.util.Map;  
  5.   
  6. import org.codehaus.xfire.client.Client;  
  7. import org.codehaus.xfire.client.XFireProxyFactory;  
  8. import org.codehaus.xfire.service.Service;  
  9. import org.codehaus.xfire.service.binding.ObjectServiceFactory;  
  10. import org.codehaus.xfire.transport.http.CommonsHttpMessageSender;  
  11.   
  12. public class SayHiClient{  
  13.   public static void main(String args[]) {  
  14.     String serviceURL = "http://localhost/stove/services/SayHiService";  
  15.     Service serviceModel = new ObjectServiceFactory().create(SayHiService.class,null,"http://cn.com.pansky/SayHiService",null);  
  16.   
  17.     XFireProxyFactory serviceFactory = new XFireProxyFactory();  
  18.   
  19.     try{  
  20.       SayHiService service = (SayHiService) serviceFactory.create(serviceModel, serviceURL);  
  21.       Client client = Client.getInstance(service);  
  22.       //client.addOutHandler(new OutHeaderHandler());  
  23.   
  24.       // disable timeout  
  25.       client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, "1");  
  26.   
  27.       String hello = service.sayHi("張山瘋");  
  28.       System.out.println("服務器對[張山瘋] 的回答是:" + hello );  
  29.   
  30.       hello = service.sayHi(null);  
  31.       System.out.println("服務器胡言亂語說:" + hello );  
  32.   
  33.     } catch (MalformedURLException e) {  
  34.       e.printStackTrace();  
  35.     }  
  36.   }  
  37. }  

 編譯這個類,再執行一下,服務器服務的結果是:

2008-5-22 17:39:17 org.apache.commons.httpclient.HttpMethodBase writeRequest
信息: 100 (continue) read timeout. Resume sending the request
2008-5-22 17:39:17 org.apache.commons.httpclient.HttpMethodBase readResponse
信息: Discarding unexpected response: HTTP/1.1 100 Continue
服務器對[張山瘋] 的回答是:張山瘋, 你吃了嗎?沒吃回家吃去吧。
2008-5-22 17:39:20 org.apache.commons.httpclient.HttpMethodBase writeRequest
信息: 100 (continue) read timeout. Resume sending the request
2008-5-22 17:39:20 org.apache.commons.httpclient.HttpMethodBase readResponse
信息: Discarding unexpected response: HTTP/1.1 100 Continue
服務器胡言亂語說:連名字也不肯告訴我嗎?

好了,WebService佈署成功。

下課!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章