級別: 中級
Jarek Gawor (jgawor@us.ibm.com), Advisory Software Engineer, IBM
Lin Sun (linsun@us.ibm.com), 顧問軟件工程師, IBM
2007 年 10 月 18 日
隨著 Java? EE 5 的出現(xiàn)和 JAX-WS 的引入,開發(fā)和部署 Web 服務變得比以前任何時候都要容易得多。了解如何使用 IBM? WebSphere? Application Server Community Edition V2.0(可以免費使用的 IBM 應用服務器上提供的最新版本,它是基于 Apache Geronimo 2.0 的)構(gòu)建 JAX-WS 客戶端和服務,并且立即開始構(gòu)建您的第一個 JAX-WS Web 服務項目。
引言
IBM WebSphere Application Server Community Edition V2.0(以下簡稱為 Community Edition)是構(gòu)建于 Apache Geronimo 2.0 之上的應用服務器,而 Apache Geronimo 2.0 是由 Apache 軟件基金會創(chuàng)建的開放源代碼應用服務器。Community Edition 服務器是一個全面兼容的、并且經(jīng)過認證的 Java Platform, Enterprise Edition 5.0 (Java EE 5) 容器,它適用于從開發(fā)環(huán)境到企業(yè)級部署的所有工作。
Java EE 5 引入了許多新的和經(jīng)過更新的特性,如 Enterprise JavaBeans? 3.0 (EJB 3),并且還通過使用注釋和依賴關(guān)系注入簡化了應用程序的開發(fā)和部署。Java API for XML-based Web services(JAX-WS)2.0 也是 Java EE 5 中引入的新特性之一。
JAX-WS
JAX-WS 2.0 是 Java EE 5 中新的 Web 服務堆棧,設計用于取代基于 Web 服務的舊的 Java API for XML-Based RPC (JAX-RPC) 1.1。JAX-WS 添加了大量新的特性,并在 JAX-RPC 上進行很大的改進,為以下的功能提供了支持:
 | JAX-WS 引擎 Community Edition 使用 Apache Axis2 1.3 作為它的 JAX-WS 引擎。盡管可以配置 Apache Geronimo 2.0 以使用 Apache CXF 作為備選 JAX-WS 引擎,但是現(xiàn)在 Community Edition 中僅提供了對 Apache Axis2 引擎的支持。 |
|
- Java Architecture for XML Binding (JAXB) 2.0。
- 簡單對象訪問協(xié)議 (SOAP) 1.2,以及 SOAP 1.1。
- Web 服務描述語言 (WSDL) 2.0,以及 WSDL 1.1。
- 用于改進的 Web 服務互操作性的 Web 服務互操作性 (WS-I) 基本概要 1.1。
JAX-WS 的一個重要特性是使用注釋簡化 Web 服務客戶端和端點的開發(fā)和部署。使用注釋簡化代碼并減少(甚至在某些情況下完全消除)對部署描述符的需要。
開發(fā) Web 服務端點
端點實現(xiàn)
使用 JAX-WS 來創(chuàng)建基本的 Web 服務是非常容易的:只需要使用 @WebService 注釋來注釋相應的類。清單 1 顯示了提供簡單 add() 函數(shù)的一個 JAX-WS 計算器服務的最簡單實現(xiàn)。
清單 1. Calculator Web 服務實現(xiàn)
import javax.jws.WebService;
@WebService()
public class Calculator {
public int add(int value1, int value2) {
System.out.println("adding " + value1 + " and " + value2);
return value1 + value2;
}
} |
就是這么簡單!要部署和發(fā)布一個 JAX-WS Web 服務,您只需要編寫經(jīng)過注釋的 Web 服務實現(xiàn)即可。您并不需要編寫任何部署描述符,如 web.xml 或者 webservices.xml,或者創(chuàng)建一個 WSDL 文件。在部署期間,服務器將自動地更新或者生成這些描述符。當然,仍然可以提供這些描述符以覆蓋缺省值并對部署工作進行自定義。例如,如果沒有提供 web.xml 文件,那么在部署期間,服務器將自動生成一個 web.xml 文件:
- 生成的 web.xml 文件將包含用于 Web 服務的 Servlet 映射。
- 這個 Servlet 映射指定了觸發(fā)給定 Web 服務的 URL 地址中的一部分。
- 在缺省情況下,將該地址設置為 Web 服務名。在這個示例中,Web 服務的名稱是 CalculatorService,因此,可以通過 /CalculatorService 地址訪問這個 Calculator Web 服務。您可以通過為這個 Web 服務使用不同的 Servlet 映射條目來提供自定義 web.xml 文件,從而更改缺省地址。
另外,請注意,這個服務類并沒有實現(xiàn)任何接口。在 JAX-WS 中,Web 服務不需要實現(xiàn)或者提供服務端點接口 (SEI)。在這樣的情況下,SEI 將隱含于服務實現(xiàn)類中,正如這個示例中所示。
另外,因為 JAX-WS 使用 JAXB 進行所有的數(shù)據(jù)綁定,所以不再需要 jaxrpc-mapping 文件。
構(gòu)建和部署服務
下面的步驟描述了如何構(gòu)建和部署該服務??紤]到本文的目的,我們使用 Apache Maven 版本 2.0.5 或者更高版本來構(gòu)建示例代碼:
 | 部署警告消息 在部署期間,您可能會看到一條警告消息,該消息指出您的 Web 應用程序沒有包含 WEB-INF/geronimo-web.xml 部署計劃。對于這個示例來說,這條消息是可以忽略的,因為它并不包含任何需要解析的資源引用。 |
|
- 下載本文所包含的示例文件,并將其解壓縮到您所選擇的目錄中。我們將這個目錄稱為 sample_install。
- 通過執(zhí)行 sample_install\jaxw-calculator\service 目錄中的
mvn install
命令,構(gòu)建服務代碼。這個 Maven 命令將編譯服務代碼,并在 target/subdirectory 中創(chuàng)建 jaxws-calculator-service-1.0.war 文件。 - 啟動 Community Edition 服務器(如果它還沒有運行的話)。使用管理控制臺來部署 WAR 文件或者執(zhí)行清單 2 中的命令,其中 wasce_install 是 Community Edition 的安裝目錄。
清單 2. 部署服務 WAR 文件
wasce_install\bin\deploy.bat --user system -password manager deploy
sample_install\jaxws-calculator\service\target\jaxws-calculator-service-1.0.war |
- 通過在您的 Web 瀏覽器中打開 http://localhost:8080/jaxw-calculator-service-1.0/CalculatorService?wsdl,檢查是否成功地發(fā)布了該服務。如果成功地部署了該服務,并且該服務正在運行,那么服務器應該返回為這個服務生成的 WSDL。
部署 Web 服務客戶端
要為該服務編寫一個 Web 服務客戶端,您首先需要由服務 WSDL 生成可移植的構(gòu)件。這些可移植的構(gòu)件是服務調(diào)用所需的一組類,如 SEI、服務類和 JAXB 生成的表現(xiàn)模式類型的類??梢允褂?Community Edition 中包含的 jaxws-tools 命令行工具,或者來自 Sun Microsystem? 的 wsgen 或者 wsimport 工具生成這些可移植的構(gòu)件。
生成可移植的構(gòu)件
考慮到本文的目的,您將使用 wsimport 工具來生成這些可移植的構(gòu)件。wsimport 工具將 WSDL 文件作為輸入,并生成所需的 SEI、服務和 JAXB 類。為了簡化構(gòu)建指令,可以將 wsimport 步驟集成到 Maven 構(gòu)建腳本中。這個腳本使用 wsimport Ant 任務來生成可移植的構(gòu)件。清單 3 顯示了調(diào)用 wsimport Ant 任務的 Maven 構(gòu)建腳本的代碼摘錄。
清單 3. wsimport Ant 任務
...
<wsimport
destdir="${pom.basedir}/target/classes"
sourcedestdir="${pom.basedir}/target/generated"
debug="true" keep="true"
wsdl="http://localhost:8080/jaxws-calculator-service-1.0/CalculatorService?wsdl" />
... |
在這個示例中,wsimport Ant 任務直接從該 Calculator Web 服務檢索 WSDL。Community Edition 服務器必須啟動并正在運行,并且必須正確地部署該服務,以便 wsimport 能夠正常工作。
這些構(gòu)件還可以由 Community Edition 中包含的 jaxws-tools 命令行工具,通過執(zhí)行清單 4 中顯示的命令來生成。
清單 4. 使用 jaxws-tools 命令
wasce_install\bin\jaxws-tools.bat wsimport
-s sample_install\jaxws-calculator\client\src\main\java
http://localhost:8080/jaxws-calculator-service-1.0/CalculatorService?wsdl |
客戶端實現(xiàn)
清單 5 顯示了一個基本的 Web 服務客戶端實現(xiàn)。這是一個簡單的 Servlet,它調(diào)用 Calculator Web 服務的 add() 函數(shù)并返回相應的結(jié)果。添加兩個值,將其分別作為參數(shù) x 和 y 傳遞到 Servlet。請注意,CalculatorService 類是 Service 類,而 Calculator 類是 wsimport 工具(在前面的步驟中)所生成的 SEI 類。將該客戶端編寫為一個 Servlet,以展示另一個新的 Java EE 5 特性:依賴關(guān)系注入。
清單 5. Calculator Web 服務客戶端實現(xiàn)
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceRef;
public class CalculatorClient extends HttpServlet {
@WebServiceRef CalculatorService service;
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
int x = Integer.parseInt(req.getParameter("x"));
int y = Integer.parseInt(req.getParameter("y"));
Calculator calculator = service.getCalculatorPort();
int sum = calculator.add(x, y);
resp.getWriter().println(x + " + " + y + " = " + sum);
}
} |
對服務變量的 @WebServiceRef 注釋將使得服務器自動地在部署描述符中添加一個服務引用條目,在運行時,查找并將這個引用的值注入到該變量。以前在 Java 2 Platform, Enterprise Edition (J2EE) 中,不得不手工地完成這兩個任務,您必須在部署描述符中明確地定義該服務引用,然后編寫額外的代碼以執(zhí)行 JNDI 查找,獲取實際的引用。
因為將 CalculatorClient 作為一個常規(guī) Servlet,所以為了定義和發(fā)布該 Servlet,仍然需要一個 web.xml 文件。然而,web.xml 文件變得更加簡單,如清單 6 所示,因為它不再需要定義服務引用。
清單 6. web.xml
<web-app xmlns="http://java./xml/ns/javaee"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xsi:schemaLocation="http://java./xml/ns/j2ee
http://java./xml/ns/j2ee/web-app_2_5.xsd"
version="2.5">
<display-name>JAX-WS Client Sample</display-name>
<servlet>
<display-name>JAX-WS Client Sample Servlet</display-name>
<servlet-name>CalculatorClientServlet</servlet-name>
<servlet-class>org.apache.geronimo.example.jaxws.CalculatorClient</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CalculatorClientServlet</servlet-name>
<url-pattern>/client</url-pattern>
</servlet-mapping>
</web-app> |
構(gòu)建和部署客戶端
 | 模塊啟動依賴關(guān)系 在這個示例中,客戶端直接從該服務檢索 WSDL,因此,必須在該客戶端模塊啟動之前啟動該服務的 WAR 模塊。如果首先啟動客戶端模塊,那么該客戶端將不能正常工作。修改 wasce_install\var\config\config.xml 配置文件,以更改模塊啟動的順序。 |
|
遵循下面的步驟以構(gòu)建和部署客戶端:
- 通過執(zhí)行 sample_install\jaxw-calculator\client 目錄中的
mvn install
命令構(gòu)建客戶端代碼。這個 Maven 命令將首先生成客戶端構(gòu)件,然后編譯客戶端代碼,最后在 target/subdirectory 目錄中創(chuàng)建 jaxws-calculator-client-1.0.war 文件。 - 使用 Community Edition 管理控制臺以部署 WAR 文件,或者執(zhí)行清單 7 中的命令。
清單 7. 部署客戶端 war 文件
wasce_install\bin\deploy.bat --user system -password manager deploy
sample_install\jaxws-calculator\client\target\jaxws-calculator-client-1.0.war |
測試這個 Web 服務示例
在部署了該客戶端 war 文件之后,在您的 Web 瀏覽器中打開 http://localhost:8080/jaxw-calculator-client-1.0/client?x=5&y=10,以調(diào)用 CalculatorClient Servlet,而它反過來將調(diào)用 Calculator Web 服務。在 URL 中指定了要添加的 x 和 y 值。在調(diào)用該 Web 服務之后,Servlet 將返回加法運算的結(jié)果。圖 1 顯示了 Servlet 的預期輸出。
圖 1. Servlet 的結(jié)果
結(jié)束語
由于 Java EE 5 的改進和 JAX-WS 的引入,開發(fā)和部署 Web 服務變得比過去任何時候都要簡單得多。本文說明了如何使用 WebSphere Application Server Community Edition V2.0 構(gòu)建 JAX-WS 客戶端和服務,并在這個過程中突出了 Java EE 5 和 JAX-WS 的某些新特性。現(xiàn)在在 Community Edition 中開始您的第一個 JAX-WS Web 服務項目,并繼續(xù)您的工作!
作者簡介
 |

|  | Jarek Gawor 是 IBM 的一名顧問軟件工程師,在北卡羅萊納州三角研究工業(yè)園的 Software Group 工作。他是 Apache Geronimo 的參與者和 PMC 成員。他獲得了伊利諾伊斯理工大學 (Illinois Institute of Technology) 的計算機科學碩士學位。 |
 |

|  | Lin Sun 是北卡羅來納州三角研究園的一名顧問軟件工程師,在 Software Group WebSphere Application Server Community Edition Development 小組工作。她擁有教堂山北卡大學的信息科學碩士學位。 |
本文轉(zhuǎn)載:
http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0709_gawor/0709_gawor.html