Eclipse下使用Apache CFX開發部署檔案上傳的WebService
配置和部署
該樣本將展示如何配置和開發一個運行在伺服器上的基於 CXF 的 Web 服務,該服務會上傳用戶端提交的檔案。參見下列規範。
Tomcat Web 服務器 5.5 或更高版本:Tomcat servlet 引擎是一個開源包,是 Apache Software Foundation 的 Jakarta 項目的一部分。它是 servlet 和 JSP 規範的官方參考實現。Tomcat 可以作為一個獨立的 Web 服務器使用,也可以作為一個 servlet/JSP 引擎實現。可以從
http://tomcat.apache.org/download-60.cgi 下載 Tomcat 的最新發行版。
Apache-cxf-2.3. 或更高版本: Apache CXF 是一個開源服務架構。CXF 協助您使用前端編程 API(如 JAX-WS 和 JAX-RS)構建和開發服務。這些服務可以支援各種協議,如 SOAP、XML/HTTP、RESTful HTTP 或 CORBA,並可以使用多種傳輸方式,如 HTTP、JMS 或 JBI。您可以從
http://cxf.apache.org/download.html 下載最新版本。
Eclipse IDE:一種整合式開發環境 (IDE),集編寫、編輯、編譯和運行電腦程式的所有工具於一體。並且,Eclipse 提供了出色的整合式開發環境。您可以在
www.eclipse.org 找到 eclipse 的最新發行版。
設置環境
- 在系統中安裝 Jdk 1.5 或更高版本。
- 下載了 apache-cxf 發行版後,設定 CXF_HOME 環境變數。
- 下載 Tomcat 的最新發行版,並設定 TOMCAT_HOME 環境變數。
創建 Web 服務
- 在 JavaEE 透視圖中 啟動 Eclipse,並選擇
File > New > Other > Dynamic Web Project,建立名為 ‘CxfService’ 的項目。
- 展開 CxfService Project 選項卡,選擇
Java Resource: src 並建立 ‘com.ibm.uploadbean’ 包。
- ‘com.ibm.uploadbean’ 包將包含一個簡單的 java bean 類,該類將擷取並設定檔案名稱、檔案類型和 DataHandler 類型。該 bean 將作為參數傳遞來調用該服務。因此,在該包下建立一個類,並命名為 ‘FileUploader’。
package com.ibm.uploadbean; import javax.activation.DataHandler;public class FileUploader{ private String Name; private String FileType; private DataHandler Dfile; public String getName() { return this.Name; } public void setName(String Name) { this.Name = Name; } public DataHandler getDfile() { return this.Dfile; } public void setDfile(DataHandler Dfile) { this.Dfile = Dfile; }public String getFileType() { return FileType;}public void setFileType(String FileType) { this.FileType = FileType;}}
- 每個 Web 服務都需要一個 Service Endpoint Interface (SEI),通過該介面用戶端可以調用實作類別。現在選擇
Java Resource: src,建立另一個名為 ‘com.ibm.uploadservice’ 的包。
- 建立一個名為 ‘UploadSEI’ 的介面,其中包含 ‘uploadFile’ 方法
package com.ibm.uploadservice;import javax.jws.WebParam;import javax.jws.WebService;import com.ibm.uploadbean.FileUploader;@WebServicepublic interface UploadSEI { void uploadFile(@WebParam(name="Dfile") FileUploader Dfile);}
6. 建立一個名為‘UploadServiceImpl’的服務實作類別,它在‘com.ibm.uploadservice’包的內部實現介面。該類定義了實現方法 uploadFile,後者使用 FileUploader bean
作為其參數。
package com.ibm.uploadservice;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import javax.activation.DataHandler;import javax.jws.WebService;import com.ibm.uploadbean.FileUploader;@WebService(endpointInterface = "com.ibm.uploadservice.UploadSEI",serviceName = "UploadService")public class UploadServiceImpl implements UploadSEI{public void uploadFile(FileUploader Dfile) {DataHandler handler = Dfile.getDfile();try { InputStream is = handler.getInputStream(); OutputStream os = new FileOutputStream(new File("E:/uploads/" + Dfile.getName() +"."+ Dfile.getFileType())); byte[] b = new byte[100000]; int bytesRead = 0; while ((bytesRead = is.read(b)) != -1) {os.write(b, 0, bytesRead); } os.flush(); os.close(); is.close();} catch (IOException e) { e.printStackTrace();} } }
- “OutputStream” 將把檔案儲存到提供的指定位置。
- 下一步是建立設定檔 ‘cxf.xml’,該檔案會根據實作類別 ‘UploadServiceImpl’ 建立 JAX-WS 端點。確保該檔案位於 ‘src’ 根資料夾中,否則根據您的檔案路徑編輯 Web.xml。
<?xml version="1.0" encoding="UTF-8"?><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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://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="uploadfile" implementor="com.ibm.uploadservice.UploadServiceImpl" address="/UploadWS"> <jaxws:properties> <entry key="mtom-enabled" value="true"/> </jaxws:properties> </jaxws:endpoint></beans>
- 編輯 Web-INF 檔案夾中的 ‘Web.xml’ 檔案。
<?xml version="1.0" encoding="UTF-8"?><Web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:Web="http://java.sun.com/xml/ns/javaee/Web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/Web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>CxfService</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:cxf.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> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </Web-app>
- 在 WebContent > Web-INF 下建立名為 ‘lib’ 的檔案夾(參見圖 5),然後在 lib 檔案夾中包括以下 .jar 檔案。您可以在已下載的 CXF 分配庫中找到所有這些 jar 檔案。
aopalliance-1.0.jar
asm-2.2.3.jar
commons-lang-2.4.jar
commons-logging-1.1.jar
cxf-api-2.1.5.jar
cxf-common-schemas-2.1.5.jar
cxf-common-utilities-2.1.5.jar
cxf-rt-bindings-soap-2.1.5.jar
cxf-rt-bindings-xml-2.1.5.jar
cxf-rt-core-2.1.5.jar
cxf-rt-databinding-jaxb-2.1.5.jar
cxf-rt-frontend-jaxws-2.1.5.jar
cxf-rt-frontend-simple-2.1.5.jar
cxf-rt-transports-http-2.1.5.jar
cxf-rt-ws-addr-2.1.5.jar
cxf-tools-common-2.1.5.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.9.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
spring-Web-2.0.8.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.6.jar
xml-resolver-1.2.jar
XmlSchema-1.4.5.jar
- 按右鍵項目,選擇 Export > WAR file(參見圖 7)。複製 WAR 檔案並粘貼到 Tomcat_Home 下的 Webapps 目錄。啟動 Tomcat 伺服器。
- 啟動 tomcat 伺服器後,Web 服務將被部署到伺服器上。進入 Tomcat Manager,輸入使用者名稱和密碼,然後登入。您會發現已部署的名為 ‘CxfService’ 的服務,單擊該服務,將看到可用的服務及其 WSDL 位置。單擊 location 超連結,查看 WSDL。
Service Endpoint -
http://localhost:8080/CxfService/UploadWS
WSDL 位置 - http://localhost:8080/CxfService/UploadWS?wsdl
產生 Stub
要調用服務,用戶端必須知道
Service Endpoint Interface 和 bean 檔案,後者將作為參數進行調用。要獲得這些內容,用戶端可以通過服務的
WSDL 建立 stub。
CXF
發行版提供了一個名為 ‘wsdl2java.bat’ 的工具,該工具可以為特定服務建立
stub,同時為 WSDL 位置提供一些額外的參數。
從命令提示字元中訪問 $(CXF_HOME) 的 bin 目錄,並輸入以下命令。
wsdl2java
–
client
–
verbose http://localhost:8080/CxfService/UploadWS?wsdl
這將運行 bin 目錄中的 wsdl2java.bat 檔案。‘-client’
選項為用戶端主線產生開始(starting point)代碼。‘–verbose’
選項在產生代碼的過程中顯示注釋。參見圖
9。
在成功執行命令後,將發現在 $(CXF_HOME)/bin 目錄的 ‘com.ibm.uploadservice’
包下建立了 stub。
創建用戶端
接下來,我們將建立用戶端項目,以便可以使用 Web 服務。在本例中,用戶端是一個 POJO 用戶端,您還可以建立一個需要 Web 容器的用戶端。執行以下步驟,開發一個用戶端。
- 在 Eclipse 中,選擇 File > New > Other > Dynamic Web project,建立一個名為 ‘CxfClient’ 的新項目。
- 建立一個名為 ‘com.ibm.uploadservice’ 的包(如在 stub 中),並將所有產生的 stub 複製並粘貼到其中。
- 建立另一個名為 ‘com.ibm.client’ 的包。在該包中建立一個名為 ‘Client’ 的新類。該類將通過產生的 stub 調用已開發的服務。該類將包含 main() 方法,因此執行將從這裡開始。
package com.ibm.client;import java.io.File;import javax.activation.DataHandler;import javax.activation.DataSource;import javax.activation.FileDataSource;import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import com.ibm.uploadservice.*;public final class Client { public static void main(String args[]) throws Exception { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.getInInterceptors().add(new LoggingInInterceptor()); factory.getOutInterceptors().add(new LoggingOutInterceptor()); factory.setServiceClass(UploadSEI.class); factory.setAddress ("http://localhost:8080/CxfService/UploadWS"); UploadSEI client =(UploadSEI) factory.create(); FileUploader file=new FileUploader(); file.setName("Partha"); file.setFileType("doc"); DataSource source = new FileDataSource(new File("D:/my_upload_doc.doc")); file.setDfile(new DataHandler(source)); client.uploadFile(file); System.exit(0); } }
- 不要忘記在 WebContent > Web-INF > lib 中包含前面提到的 .jar 檔案。
- ‘DataSource’ 對象原始碼將包含上傳檔案的理想位置。在本例中為 ‘D:/my_upload_doc.doc’,可根據您的檔案進行相應修改。
- setName("Partha") 是所上傳檔案的儲存名。修改
setFileType("doc") 參數可相應地設定檔案類型。
- 您可能會在 ‘file.setDfile’ 中得到一個類型匹配錯誤,這可能是因為產生的 ‘FileUploade.java’ 有一個 ‘byte[]’ 變數,而不是 ‘DataHandler’ 變數。將
byte[] 修改為 DataHander 就可以解決該問題。您還應當在其中匯入 ‘javax.activation.DataHandler’。在任何情況下,引用
清單 1 中建立服務時使用的 bean 類。
- 要運行用戶端,按右鍵 Client.java 檔案並選擇 Run as > Java Application。如果沒有發生錯誤的話,您會發現您的檔案以給定的名稱儲存在服務指定的位置中。