天天看點

Web Service修煉之一XFire入門一、XFire知識二、XFire開發

一、XFire知識

1、Web Service架構

    web Service是獨立的、子產品化的應用,能夠通過網際網路來描述、釋出、定位以及調用。在Web Service的體系架構中包括三個角色:服務提供者(Service Provider)、服務請求者(Service Requestor)、服務注冊器(Service Registry)。角色間主要有三個操作:釋出(Publish)、查找(Find)、綁定(Bind)。

Web Service修煉之一XFire入門一、XFire知識二、XFire開發

2、Web Service協定标準

簡單對象通路協定(SOAP)

    SOAP是Simple Object Access Protocol的縮寫,是一種基于XML的不依賴傳輸協定的表示層協定,用來在分散或分布式的應用程式之間友善地以對象的形式交換資料。在SOAP的下層,可以是HTTP/HTTP,也可以是SMTP/POP3,還可以是為一些應用而專門設計的特殊的通信協定。

    SOAP包括三個主要部分:

         SOAP封裝結構:定義了一個整體架構,以表示消息中包含什麼内容,誰來處理這些内容以及這些内容是可選的或是必需的。

         SOAP編碼規則:定義了用以交換應用程式定義的資料類型的執行個體的一系列機制。

         SOAP RPC表示:定義了一個用來表示遠端過程調用和應答的協定。

Web Service描述語言(WSDL)

    WSDL是Web Service Des cription Language的縮寫,該語言将網絡服務定義成一個能交換消息的通信端點集,為分布式系統提供了幫助文檔,同時也可作為自動實作應用間通信的解決方案。

統一描述、發現和內建協定(UDDI)

  UDDI是一套基于Web的、分布式的、為Web Service提供的、資訊注冊中心的實作标準規範,同時也包含一組使企業能将自身提供的Web Service注冊,以使别的企業能夠發現的通路協定的實作标準。

3、XFire概述

    XFire 是 codeHaus 組織提供的一個開源架構,它建構了 POJO 和 SOA 之間的橋梁,主要特性就是支援将 POJO 通過非常簡單的方式釋出成 Web 服務,這種處理方式不僅充分發揮了 POJO 的作用,簡化了 Java 應用轉化為 Web 服務的步驟和過程,也直接降低了 SOA 的實作難度,為企業轉向 SOA 架構提供了一種簡單可行的方式。

XFire 目前最新的版本是 1.2.6,目前支援的特性主要包括:

· 支援将 Web 服務綁定到 POJO、XMLBeans、JAXB1.1、JAXB2.0 和 Castor;

· 支援基于 HTTP、JMS、XMPP 等多種協定通路 Web 服務;

· 支援多種 Web 服務業界重要标準如 SOAP、WSDL、Web 服務尋址(WS-Addressing)、Web 服務安全(WS-Security)等;

· 支援 JSR181,可以通過 JDK5 配置 Web 服務;

· 高性能的 SOAP 實作;

· 伺服器端、用戶端代碼輔助生成;

· 對 Spring、Pico、Plexus 等項目的支援等。

4、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

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簡單很多

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

          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++版本。

AXIS VS CXF

這兩個架構 都是從已有的開源項目發展起來的。Axis2是從Axis1.x系列發展而來。CXF則是XFire和Celtix項目的結合産品。Axis2是從底層全部重新實作,使用了新的擴充性更好.

    通過一個比較矩陣來比較Axis2和CXF變得有現實的意義。這兩個項目都開發不夠成熟,但是最主要的差別在以下幾個方面:

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。如果你需要把你的實作側重JAVA并希望和Spring內建,CXF就是更好的選擇,特别是把你的Web Service嵌入其他的程式中。如果你覺得這兩個架構的新特性對于你并沒有太大的用處,你會覺得Axis1也是不錯的選擇,你應該繼續使用它知道你有充分的理由去更換它。

二、XFire開發

1、準備開發環境

環境:MyEclipsexx +tomcat6.0+JDK1.5

xfire版本:xifre-1.2.6

XFire所需jar包:

在http://xfire.codehaus.org/下載下傳xfire1.2.6-.zip壓縮包,解壓後lib下jar包

在MyEclipse下建立一個Web Applications,命名為ws

目錄結構

Web Service修煉之一XFire入門一、XFire知識二、XFire開發

2、配置運作環境

WEB-INF目錄下建立一個web.xml檔案,檔案中輸入:xml代碼

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appid="WebApp_ID"version="2.4"

xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <servlet>

  <servlet-name>XFireServlet</servlet-name>

  <display-name>XFire Servlet</display-name>

  <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>

  </servlet>

  <servlet-mapping>

  <servlet-name>XFireServlet</servlet-name>

  <url-pattern>/servlet/XFireServlet/*</url-pattern>

  </servlet-mapping>

  <servlet-mapping>

  <servlet-name>XFireServlet</servlet-name>

  <url-pattern>/services/*</url-pattern>

  </servlet-mapping>

</web-app>

   其中主要就是引入了XFireServlet,用以處理Web Service請求,并且負責提供Web Service的WSDL,如果你釋出了一個名為BookService的WebService,則可以通過網址:
   http://<伺服器>[:端口]/<webapp名>/services/來通路這個WebService,并且通過位址:http://<伺服器>[:端口]/<webapp名>/services/BookService?wsdl來得到這個WebService的WSDL資訊。      

3、開發應用程式

    在src檔案夾下建立一個package:com.test.ws,在這個包下面建立一個接口:

 業務接口Java代碼

package com.test.ws;

publicinterface SayHelloService {

//調用的業務方法

public String sayHello(String name);

}

        這個接口是告訴伺服器你的WebService哪些方法可以被使用者調用的。我們再來寫一個SayHelloService的實作類,以完成業務邏輯:

業務Java代碼

package com.test.ws;

publicclassSayHelloServiceImplimplements SayHelloService {

//業務實作方法

public String sayHello(String name) {

if(name==null){

return"你叫什麼名字呢?";

}

return name+",早上好,還沒有上學去嗎 ?";

}

}

}

    這個類實作了sayHello方法,該方法是可以通過WebService調用通路到的。 接下來釋出WebService

4、配置部署服務

在目錄src下建立目錄結構META-INF/xfire,然後在該檔案夾下建立一個XML檔案:services.xml,檔案内容如下:      

xml代碼

<?xmlversion="1.0"encoding="UTF-8"?>

<!-- START SNIPPET: services -->

<beansxmlns="http://xfire.codehaus.org/config/1.0">

<service>

<name>SayHelloService</name>

<namespace>http://com.test.ws/SayHelloService</namespace>

<serviceClass>com.test.ws.SayHelloService</serviceClass>

<implementationClass>com.test.ws.SayHelloServiceImpl</implementationClass>

</service>

</beans>

<!-- END SNIPPET: services -->

這個檔案定義一個WebService:SayHelloService,并同時定義了接口和實作類。将上面建立的SayHelloService釋出成Web服務。

其中各元素的功能如下:

service

service标簽和它所包含的xml内容為釋出成Web 服務的POJO 提供完整的描述。

name

Web服務被釋出時所采用的唯一名稱。

namespace

Web服務釋出時所使用的命名空間。

serviceClass

Web服務接口類的全名,包括包名和類名。

implemetationClass

Web 服務實作類的全名,包括包名和類名。

把工程ws部署到tomcat下

5、運作測試應用

啟動Tomcat

再打開浏覽器,輸入:http://localhost:8080/ws/services,

伺服器傳回的結果如下:

Web Service修煉之一XFire入門一、XFire知識二、XFire開發

WebService已經布署成功了,打開WSDL資訊:

    http://localhost:8080/ws/services/SayHelloService?wsdl。

    其中 sayHelloService是配置檔案中 service\name元素所定義的内容,”wsdl”參數表示檢視該Web服務的WSDL(Web服務描述語言)檔案。

Web Service修煉之一XFire入門一、XFire知識二、XFire開發
    注意:XML的空格或者有些字元在不同的編碼下,會出現亂碼,到時XML解析會出錯。我這邊運作這個servers.xml執行個體,由于編碼不符合UTF-8,配置内容是其他編碼形式,導緻XML解析報錯:      

org.springframework.beans.factory.BeanCreationException:

Error creating bean with name

'org.codehaus.xfire.spring.ServiceBean' defined in class path

resource [META-INF/xfire/services.xml]: Error setting property

values; nested exception is

org.springframework.beans.NotWritablePropertyException: I

nvalid property '????' of bean class

[org.codehaus.xfire.spring.ServiceBean]:

Bean property '????' is not writable or has an invalid setter

method: Does the parameter type of the setter match the return

typeof the getter?

org.springframework.beans.NotWritablePropertyException:

Invalid property '????' of bean class

[org.codehaus.xfire.spring.ServiceBean]:

Bean property '????' is not writable or has an invalid

setter method: Does the parameter type of the setter

match the return type of the getter?

6、模拟遠端調用

用戶端Java代碼

package com.test.ws;

import java.net.MalformedURLException;

import org.codehaus.xfire.client.Client;

import org.codehaus.xfire.client.XFireProxyFactory;

import org.codehaus.xfire.service.Service;

import org.codehaus.xfire.service.binding.ObjectServiceFactory;

import org.codehaus.xfire.transport.http.CommonsHttpMessageSender;

publicclass SayHelloClient {

publicstaticvoid main(String args[]) {

String serviceURL ="http://localhost:8080/ws/services/SayHelloService";

//建立service對象

Service serviceModel =new ObjectServiceFactory().create(SayHelloService.class);

XFireProxyFactory serviceFactory =new XFireProxyFactory();

try{

//擷取服務對象

SayHelloService service = (SayHelloService) serviceFactory.create(serviceModel, serviceURL);

Client client = Client.getInstance(service);

//忽略http連接配接的逾時時間,0為不設定逾時時間,》=1為逾時毫秒數

client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT,"0");

String msg = service.sayHello("大兵");

System.out.println("伺服器對[大兵]的回複:" + msg);

msg = service.sayHello(null);

System.out.println("伺服器對你的回複:" + msg);

}catch (MalformedURLException e) {

e.printStackTrace();

}

}

用戶端運作結果:

伺服器對[大兵]的回複:大兵,早上好,還沒有去工作嗎?

伺服器對你的回複:你叫什麼名字呢?

注意:當用戶端設定http連接配接逾時為1毫秒時

Client client = Client.getInstance(service);

client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, "1");

會出現如下錯誤提示:

2013-9-12 11:21:02 org.codehaus.xfire.transport.http.HttpChannel

sendViaClient

嚴重:java.net.SocketTimeoutException: Read timed out

Exception in thread "main"

org.codehaus.xfire.XFireRuntimeException:

Could not invoke service..

Nested exception is org.codehaus.xfire.fault.XFireFault:

Couldn't send message.

org.codehaus.xfire.fault.XFireFault: Couldn't send message.

at org.codehaus.xfire.fault.XFireFault.createFault

(XFireFault.java:89)

at org.codehaus.xfire.handler.OutMessageSender.invoke

(OutMessageSender.java:30)

at org.codehaus.xfire.handler.HandlerPipeline.invoke

(HandlerPipeline.java:13

    從例子實作的過程中,我們可以發現XFire架構最大化的發揮了POJO 的作用,減少了SOA 實施時對架構本身的依賴,降低了SOA實施的難度,企業實施SOA 時并不需要增加太多的投入就可以實作目标。

最後附上工程源碼

繼續閱讀