WebService流行框架之Axis和CXF

2020-08-13 16:44:37

前言

上節課我們對WebService進行了簡單的介紹,對於其所應用到的技術有了一定的瞭解。今天主要講解下WebService的兩個流行的框架Axis和CXF。

正題

一、伺服器端發佈WebService

在講解之前,我們先來看一下這篇部落格主要講解的內容:

在这里插入图片描述

每一種框架都有自己的特點,有自己的側重,但是他們的共同之處在於對發佈WebService進行了封裝,所以我們只需編寫一個組態檔或者使用@WebService註解就可以發佈WebService,我們這裏着重說一下他們各自的特點:

1.Axis1

Axis1有兩種發佈方式:

1)JWS方式

a.這種方式很簡單,只需要將原始碼java檔案放到AXIS_HOME下面 下麪,然後將後綴改爲.jws,這樣,Axis 會自動編譯.jws檔案,並把它自動加入到Java WebServie的服務中。

b.但是這種方式的缺點是:只能是java原始碼,同時類中不能含有包名。

2)WSDD方式

1.寫一個java類(需要引入axis的jar包)

2.設定web.xml檔案(設定AxisServlet,AdminServlet,SOAPMonitorService和AxisHTTPSessionListener)

3.寫一個deloy.wsdd檔案,部署專案(tomcat啓動就可以部署專案)

安裝axis1到tomcat:

1.Axis官方網站:http://ws.apache.org/axis/,可以在官網下載最新1.4的包:axis-bin-1_4.zip

2.將解壓後的axis-1_4\webapps\下的axis目錄考到%TOMCAT_HOME%/Webapps/目錄下

3.啓動tomcat後在瀏覽器裡輸入http://localhost:port/axis

4.點選上圖中的Validataion鏈接,頁面上會提示已經有的包和缺少的包的資訊,根據提示將必須的包下載全,

將這些類包複製到%tomcathome%/webapps/axis/WEB-INF/lib/目錄下

重新啓動tomcat,直到Validation頁面中看不到有Error與Warning的提示資訊。

2.Axis2

用戶端對於數據型別的不同有兩種呼叫方式:RPCServiceClient和OMAbstractFactory方式

1)RPC方式:

處理基本的數據型別,如String,int等

2)OM方式:

可處理基本數據型別和自定義數據型別(比如java實體物件):通過xml的參數形式進行傳遞(傳遞的參數需要轉換爲OMElement)

注:如果參數或返回值是List型別則需要進行手動處理轉換(手動編寫一個伺服器端對傳遞過來的參數進行處理,將傳過來的OMElement手動轉換爲List型別,呼叫執行方法,然後將返回的List型別再轉換爲OMElement傳回用戶端)

Axis2發佈檔案(編寫services.xml)

1.將官網下載的axis2.war包拷貝到tomcat_home/webapps下,執行即會解壓

2.將其conf,modules和services資料夾拷貝到專案的WEB-INF下面 下麪,並將lib下的jar包拷貝到web-inf/lib下面 下麪

3.設定Web.xml(設定AxisServlet和AxisAdminServlet)

4.編寫services下面 下麪的services.xml檔案,指定要發佈的類

3.CXF

CXF發佈WebService有三種方式:main方式,基於和不基於Spring發佈到容器

1)main方式

引入jar包,在介面和實現類上使用@WebService即可,發佈完成後即可在瀏覽器中存取url,不需要啓動tomcat等服務。

2)不基於Spring方式發佈到容器

a)引入cxf的jar包,編寫web.xml(設定自定義的CXFServlet,該CXFServlet需要繼承CXFNonSpringServlet)

b)編寫實體類,業務類和服務類(實體類需要和服務類在同一包下,否則報錯)

c)啓動Tomcat,即可發佈服務

3)基於Spring方式發佈到容器

a)web.xml設定(Spring設定,cxf封裝的CXFServlet設定)

b)applicationContext-server.xml設定

<importresource=「classpath:META-INF/cxf/cxf.xml」 />

<importresource=「classpath:META-INF/cxf/cxf-extension-soap.xml」 />

<importresource=「classpath:META-INF/cxf/cxf-servlet.xml」 />

<beanid="helloServicesBean"class=「com.ms.services.impl.HelloServicesImpl」 />

<jaxws:serverid=「helloServices」 address="/HelloServices"

serviceClass=「com.ms.services.IHelloServices」>

jaxws:serviceBean

<refbean=「helloServicesBean」/>

</jaxws:serviceBean>

</jaxws:server>

c)編寫類

實體類

服務介面(類頭使用@WebService)

服務實現(類頭使用@WebService(endpointInterface=「com.ms.services.IHelloServices」))

以上是關於Axis和CXF發佈特點及其需要注意的地方,是我做例子時的總結,有興趣的同學可以下載原始碼。

二、用戶端呼叫WebService

伺服器端將介面發佈成功後,就等着用戶端來進行呼叫了,用戶端如何並通過什麼方式來呼叫我們伺服器端發佈的wsdl檔案呢?

1.呼叫一次WebService的本質:

在这里插入图片描述

1.用戶端把呼叫方法參數,轉換生成XML文件片段(SOAP訊息,input訊息,該文件片段必須符合WSDL定義的格式),通過網路,把XML文件片段傳給伺服器

2.伺服器接收到XML文件片段,解析XML文件片段,提取其中的數據,並把數據轉換呼叫WebService所需要的參數值。

3.伺服器執行方法。

4.把執行方法得到的返回值,再次轉換生成爲XML文件片段(SOAP訊息,output訊息)——該文件片段必須符合WSDL定義的格式,通過網路,把XML文件片段傳給用戶端。

5.用戶端接收到XML文件片段,解析XML文件片段,提取其中數據,並把數據轉換呼叫WebService的返回值。

從上面呼叫本質來看,要一個語言支援WebService,唯一的要求是:該語言支援XML文件解析、生成、支援網路傳輸。

2.用戶端呼叫方式:

用戶端呼叫伺服器端方法總體來說有三種方式:

1)DII(Dynamic Invocation Interface)

採用直接呼叫方式,可以在程式中設定諸多的呼叫屬性,使用較爲靈活,但是呼叫過程卻相對繁瑣複雜,易造成程式碼膨脹且可重用性低,每次呼叫不同的Web Service都要重複進行大量編碼。

這也是我們比較常用的一種方法,就是呼叫invoke方法,傳入方法名和方法參數即可。

2)Stubs

JAX-RPC使用靜態的Stub方式包裝對底層介面的呼叫,從而提供一種更爲簡便的呼叫方式。使用該方式需要利用支援環境(比如Axis)所提供的工具根據WSDL預生成WebService用戶端的實現程式碼。因此如果服務的WSDL發生變化,就必須重新生成新的用戶端程式碼並進行重新部署。

該方法需要使用wsdl2java命令來預生成WebService用戶端程式碼,爲了支援該命令,需要安裝一些環境。

3)Dynamic Proxy

動態代理(Dynamic Proxy)的方法實現對Web Service的動態呼叫,可以在執行時根據使用者定義的Client端介面建立適配物件。從而避免了直接操作底層的介面,減少了用戶端的冗餘,遮蔽了呼叫相關的複雜性。

該方法主要在於用戶端介面,該用戶端介面需要繼承java.rmi.Remote介面,然後將伺服器端的介面中的方法copy過來。

小結:

從發展歷史角度來看,很容易理解他們的側重點,Axis1最早,所以注重的只是簡單的發佈介面即可,之後隨之Axis2對其進行了優化,可以支援自定義參數,但並不完善,所以CXF的出現對這一功能進行了完善並且適應了潮流,實現了與Spring的整合,跟這些比起來,EJB3中對於WebService的支援只需要使用一個@WebService即可完成,所以軟體的開發是讓使用者變傻,而我們學習這些是爲了理解其原理和本質。