剛開始接觸的是Xfire,由於xfire幾年沒有維護了,相容性不是很好,同時會自動在wsdl中產生一些垃圾的東西,特別是如果類中的欄位用到了xfire字的泛型,則wsdl非常的龐大,並且用戶端根據wsdl產生的程式碼也特別多.本來只要定義好了wsdl,就只需要把這個wsdl文檔給使用者產生用戶端的,但是由於xfire的不相容性,經常需要把xfire的web service運行後的wsdl拷貝出來給使用者.
所以,今天決定放棄xfire了,改用CFX。由於cfx是Apache的一個開源項目,在相容性方面那是不比說的了。首先定義好一個wsdl文檔,定義的時候就沒有必要像在xfire那種考慮元素的類型、約束等。同一個wsdl文檔用xfire產生服務端,再用別的工具如wsdl.exe產生用戶端,如果沒有好好的約束和設計好,用戶端直接調用服務端是不行的,今天發現xfire的一個特點就是對於xsd的命名空間如果會自定更改為java中類的包路徑,比如wsdl文檔時這樣的:
<xsd:schema targetNamespace="http://services.sxit.com/cueapinterfaceforsi/">
則web 服務運行後的wsdl是:
<xsd:schema targetNamespace="http://cueapinterfaceforsi.services.sxit.com"/>.
這樣就不能直接用原wsdl檔案產生用戶端與web服務互動了.當然,有的人會可以利用aegis.xml來映射,不過我沒有用過,不知道行不行。但是在cfx下就不需要考慮這些問題了,直接定義好wsdl文檔,利用別的工具產生的用戶端都能正常訪問web 服務。
定義好了一個wsdl文檔後,就可以利用cfx的wsdl2server工具來產生類介面和介面實作類別,有的程式員做web服務的時候喜歡直接寫介面、類以及相關的資料類,再建立web server。其實這樣有點麻煩,光寫代碼就要寫好久,有時還要注意什麼命名空間、element的名稱啊,如果事先寫好了wsdl的話,直接利用工具產生服務端,那豈不是省了很多代碼量 ,閑話少說,還是回去主題吧。
首先在Apache網站上下載cfx包,解壓縮到某路徑,然後設定環境變數:
CXF_HOME=e:/java/apache-cxf-2.1.3,以及在path中增加 % CXF_HOME%/bin。然後就可以在控制台上輸入:
wsdl2java -impl -server CueapInterfaceForSI.wsdl來產生介面類、實作類別和其他的資料類了。-impl參數是要求產生實作類別,如果沒有這個參數,則僅僅產生介面和其他元素類。
然後搭建cfx環境,在MyEclipse中建立一個Web Server Project.類型選擇JAX-WS.項目建立成功後,把cfx檔案夾中lib目錄下所有的jar檔案拷貝到工程的lib目下中。然後把利用wsdl2java工具產生的java代碼拷貝到工程的src目錄下.然後需要修改一個地方,就是在介面的實作類別中把wsdlLocation = "file:CueapInterfaceForSI.wsdl"這個東東給刪除,不然等會運行是會提示找不到這個wsdl檔案.在web-inf目錄下建立一個beans.xml檔案,內容如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint
id="CueapInterfaceForSI"
implementor="com.sxit.services.cueapinterfaceforsi.CueapInterfaceForSIImpl"
address="/CueapInterfaceForSI" />
</beans>
然後配置web.xml:
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
運行tomcat,在url中輸入http://127.0.0.1:8080/bnetinterface/services/CueapInterfaceForSI?wsdl.查看到的wsdl內容就跟源wsdl文檔的一樣了,不用像在xfire下擔心不一致了,也沒有xfire那麼複雜和龐大。
利用.NET的wsdl工具根據源wsdl文檔產生用戶端,建立一個測試類別,建立一個測試資料,就能直接調用服務端了。傳送的資料和返回的資料都一致,再也不用擔心參數值為null了。